WinRT自定义控件第一
之前的文章中,介绍了用WPF做一个转盘按钮控件,后来需要把这个控件移植到WinRT时,遇到了很大的问题,主要原因在于WPF和WinRT还是有很大不同的。这篇文章介绍了这个移植过程,由于2次实现的控件功能完全一样,文章主要关注点放在WPF与WinRT的不同上。
定义控件模板的XAML文件在WinRT上的实现和WPF中实现一个很大的不同是,这个实现的TemplatedControl没有从ItemsControl继承,而是由Control继承手动添加了一些对集合属性的支持。不从ItemsControl继承的原因是WinRT中无法由ItemsPresenter继承,从而不能继承一个自己的ItemsPresenter并添加属性供自定义的Panel绑定。所以在WinRT的实现中直接在空间里放了一个Panel来对集合属性的元素进行布局,Panel的属性可以直接绑定到控件的依赖属性。
首先来展示一下控件模板的基本结构:
基本上分为四部分:定义状态,圆形透明背景,显示一圈小按钮的Panel以及中间的大按钮。WinRT中ZIndex附加属性被定义在Canvas上,而不像WPF中被定义在Panel上,所以WinRT的实现中不是用ZIndex附加属性实现元素的前后关系,而是通过元素在XAML中出现的顺序来保证这个关系。这是一个不小的限制,但暂时没找到什么好方法。
大按钮和圆形透明背景依然很简单:
<Ellipse Width="{TemplateBinding ShadowSize}" Height="{TemplateBinding ShadowSize}" Fill="#66559977"></Ellipse> <Border x:Name="PART_CenterBtn" VerticalAlignment="Center" HorizontalAlignment="Center" CornerRadius="15" Width="{TemplateBinding CenterSize}" Height="{TemplateBinding CenterSize}" Tag="Main" BorderThickness="{TemplateBinding BorderThickness}" BorderBrush="{TemplateBinding BorderBrush}" Background="{TemplateBinding Background}"> <TextBlock VerticalAlignment="Center" HorizontalAlignment="Center" Foreground="{TemplateBinding Foreground}" Text="{TemplateBinding CenterMenu}"> </TextBlock> </Border>这里一个很困惑的问题是中间按钮那个Border的CornerRadius始终无法绑定到控件的依赖属性。在网上找了半天,看了很多例子,都没发现有这个限制。但我这里用只要是绑定CornerRadius就变成被设置为0的效果,实在是诡异。这个问题导致目前的实现只能将CornerRadius设置为显式的固定值,从而不能通过控件的属性灵活改变中央按钮的大小。希望高手们能帮忙看看文章最后的源程序。
几个状态的定义和之前差不多,子菜单正是根据不同的状态来在收缩和展开模型来回切换。较之WPF中实现的改变就是其不再是通过ItemsPresenter间接控制Panel,而是直接控制控件中定义的Panel:
<VisualStateManager.VisualStateGroups> <VisualStateGroup x:Name="CommonStates"> <VisualState x:Name="Initial"> <Storyboard > <ObjectAnimationUsingKeyFrames Storyboard.TargetName="PART_Panel" Storyboard.TargetProperty="PanelStatus"> <DiscreteObjectKeyFrame KeyTime="0" Value="Initial" /> </ObjectAnimationUsingKeyFrames> </Storyboard> </VisualState> <VisualState x:Name="Collapsed"> <Storyboard > <ObjectAnimationUsingKeyFrames Storyboard.TargetName="PART_Panel" Storyboard.TargetProperty="PanelStatus"> <DiscreteObjectKeyFrame KeyTime="0" Value="Collapsed" /> </ObjectAnimationUsingKeyFrames> </Storyboard> </VisualState> <VisualState x:Name="Expanded"> <Storyboard > <ObjectAnimationUsingKeyFrames Storyboard.TargetName="PART_Panel" Storyboard.TargetProperty="PanelStatus"> <DiscreteObjectKeyFrame KeyTime="0" Value="Expanded" /> </ObjectAnimationUsingKeyFrames> </Storyboard> </VisualState> </VisualStateGroup> </VisualStateManager.VisualStateGroups>温馨提示: 本文由Jm博客推荐,转载请保留链接: https://www.jmwww.net/file/67667.html