WPF旋转木马/旋转元件
我正在开发一款使用相机拍摄自动照片的软件。我希望用户能够设置照片间隔。我希望看起来像一些旋转木马一样工作。WPF旋转木马/旋转元件
这是它应该是什么样子:
当我刷卡(或用鼠标拖动),应该在给定方向移动:
所选项目应始终中间,如果它是最后一个,第一个应该向右旋转(反之亦然)。
我已经添加了基本的滑动/拖动功能,它可以识别何时执行了操作以及在哪个方向上。 Hovewer,我不知道如何实际移动物品。
目前,该项目的定义是这样的:
<StackPanel x:Name="countdownContainer" Background="{StaticResource GuiSideBarBackgroundColor}" Orientation="Horizontal" HorizontalAlignment="Center">
<TextBlock Style="{StaticResource CountdownElement}" Text="3s"/>
<TextBlock Style="{StaticResource CountdownElementSelected}" Text="5s"/>
<TextBlock Style="{StaticResource CountdownElement}" Text="10s"/>
</StackPanel>
我知道动画一些基础知识,但我不知道如何动画他们就像我需要在这里。 使用其他控件而不是StackPanel和TextBlock元素会更好吗?
我基于自己上面声明的样式,但未包含在代码中。您可以在纯xaml和视图模型中执行此操作。这将是一个非常简单粗暴的例子。或者,您可以实现一个自定义控件,该控件继承某个类的层次结构,而不是控制哪个默认cust控件模板提供的默认值。我建议您查看MVVM模式和Galaxoft MVVM Light。在这个例子中,我排除了touch gestures,它们很容易实现,使用EventToCommand可以直接在你的vm或custcontrol *中使用它们。
资源
<ItemsPanelTemplate x:Key="YourItemsPanelTemplate">
<VirtualizingStackPanel Orientation="Horizontal"/>
</ItemsPanelTemplate>
<DataTemplate x:Key="YourDataTemplate">
<TextBlock Style="{StaticResource CountdownElement}" Text="{Binding .}" x:Name="PART_TextBlock"/>
<DataTemplate.Triggers>
<DataTrigger
Binding="{Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorType= {x:Type ListViewItem}},Path=IsSelected}" Value="True">
<!-- Here I'm just changing your fontsize, do whatever you want here :) -->
<Setter Property="FontSize" Value="34" TargetName="PART_TextBlock"/>
</DataTrigger>
</DataTemplate.Triggers>
</DataTemplate>
<Style x:Key="YourContainerStyle" TargetType="ListViewItem">
<Setter Property="HorizontalContentAlignment" Value="Center" />
<Setter Property="VerticalContentAlignment" Value="Bottom" />
<Setter Property="Background" Value="Transparent" />
<Setter Property="BorderThickness" Value="0" />
<Setter Property="Margin" Value="10,0,10,0" />
<Setter Property="Padding" Value="0" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type ListViewItem}">
<ContentPresenter x:Name="PART_ContentPresenter"
HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}"
Margin="{TemplateBinding Padding}"
Content="{TemplateBinding Content}"
ContentTemplate="{StaticResource YourDataTemplate}" />
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<Style x:Key="YourListBoxStyle" TargetType="ListBox">
<Setter Property="ItemContainerStyle" Value="{StaticResource YourContainerStyle}"/>
<Setter Property="ItemTemplate" Value="{StaticResource YourDataTemplate}"/>
<Setter Property="ItemsPanel" Value="{StaticResource YourItemsPanelTemplate}"/>
</Style>
还有就是你的风格,现在的XAML代码,请注意,我在这里绑定你的项目,并使用上述的样式。
XAML
<Grid>
<ListView Background="{StaticResource GuiSideBarBackgroundColor}"
Style="{StaticResource YourListBoxStyle}"
ItemsSource="{Binding CountDownElements}"
SelectedItem="{Binding SelectedItem, Mode=TwoWay}"/>
<Grid>
视图模型 Remeber设置此作为的DataContext你的看法,或将代码复制到你的代码隐藏。
public class YourViewModel : INotifyPropertyChanged
{
private ObservableCollection<string> countDownElements = new ObservableCollection<string> { "1s", "2s", "3s", "4s", "5s", "6s", "7s", "8s", "9s", "10s" };
private string selectedItem;
public ObservableCollection<string> CountDownElements
{
get { return countDownElements; }
set
{
if (Equals(value, countDownElements)) return;
countDownElements = value;
OnPropertyChanged();
}
}
public string SelectedItem
{
get { return selectedItem; }
set
{
if (value == selectedItem) return;
selectedItem = value;
OnPropertyChanged();
}
}
public event PropertyChangedEventHandler PropertyChanged;
[NotifyPropertyChangedInvocator] // remove if you don't have R#
protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
{
PropertyChangedEventHandler handler = PropertyChanged;
if (handler != null) handler(this, new PropertyChangedEventArgs(propertyName));
}
}
输出
希望它可以帮助或至少踢你在正确的方向!:)
干杯
了Stian
谢谢Stian :)我其实想过使用ListView,虽然没有尝试,但因为还有另一个问题我正在面对:如何使ListView无限(或循环)。我想达到的目的是让选中的项目始终显示在中心,并且围绕它的其他元素循环播放。如我的两张图片所示,选择“10s”时“3s”向右移动。 我是否需要重新排序集合中的元素并重新绘制ListView,或者是否有更好的方法呢? – 2014-09-12 11:06:44
@DavideDeSantis您可能需要创建自己的项目面板,我在第一个Microsoft Surface(大表格)上编写了学士论文编码。事实上,与您的问题几乎完全相同,但我无法分享此代码,因为它属于我撰写论文的公司。基本上,您可以创建一个面板,并在控制模板的面板上设置ItemsHost = true。 [这个例子已经过时了,因为Dr.WPF在2010年停止了对WPF的编码](http://drwpf.com/blog/category/panels/),但它可能会指向你正确的方向。您将需要实现IScrollInfo接口。 – 2014-09-12 15:19:56
这看起来不错,谢谢。我会研究它:) – 2014-09-13 06:22:25
你签出任意[现有转盘]的(http://wpfcarousel.codeplex.com/)控制可在那里了吗?可以为你节省一些麻烦。 – 2014-09-11 13:58:32
是的,我已经检查了一个。我想自己创建它,因为我想在过程中学习一些东西。 – 2014-09-11 14:11:11