当前位置:首页 > Windows程序 > 正文

WinRT自定义控件第一

2021-03-26 Windows程序

之前的文章中,介绍了用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