【笔记】WPF之模板控件应用
最近在捣鼓WPF的动画,想自定义一个控件模型来实现动画。
目标功能是这样:在WPF项目文件中创建一个自定义用户控件模型,该模型最外层是一个Grid,Grid布局为3行1列,第一列是一个图片按钮,第二列为主标题,第三列为副标题,XAML语句如下:
1 <Grid Name="grid" Background="Transparent"> 2 <Grid.ColumnDefinitions> 3 <ColumnDefinition></ColumnDefinition> 4 </Grid.ColumnDefinitions> 5 <Grid.RowDefinitions> 6 <RowDefinition Height="225"></RowDefinition> 7 <RowDefinition></RowDefinition> 8 <RowDefinition></RowDefinition> 9 </Grid.RowDefinitions> 10 <Button Name="btn" BorderThickness="0" BorderBrush="Transparent" Background="Transparent"> 11 <Button.Template> 12 <ControlTemplate> 13 <!--定义视觉树--> 14 <Image Name="img" Width="{TemplateBinding Button.Width}" Height="{TemplateBinding Button.Height}" Source="{TemplateBinding Button.Content}"></Image> 15 <!--定义视觉树--> 16 </ControlTemplate> 17 </Button.Template> 18 </Button> 19 <TextBlock Name="title" FontSize="24" Foreground="Blue" HorizontalAlignment="Center" Text="Title" Grid.Column="0" Grid.Row="1"></TextBlock> 20 <TextBlock Name="subtitle" FontSize="24" Foreground="Blue" HorizontalAlignment="Center" Text="Subtitle" Grid.Column="0" Grid.Row="2"></TextBlock> 21 </Grid>
注意到在第一列图片按钮处添加了控件模板,并将Image高和宽绑定到按钮的高和宽,图片源绑定到Button的Content属性上。
后台C#代码如下:
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Windows; using System.Windows.Controls; using System.Windows.Data; using System.Windows.Documents; using System.Windows.Input; using System.Windows.Media; using System.Windows.Media.Imaging; using System.Windows.Navigation; using System.Windows.Shapes; namespace HordeElves { /// <summary> /// MyButton.xaml 的交互逻辑 /// </summary> public partial class MyFirstButton : UserControl { public MyFirstButton() { InitializeComponent(); } } }
这样,我只要在需要按钮的地方实例化一个MyFirstButton的实例,并给其Content属性附上一个ImageSource对象即可。
但在做的过程中遇到了问题,我给我Button实例的Width和Height属性赋值都可以绑定到自定义控件的属性上,但给Content赋值时出现了问题,控件不显示。
btn = new MyFirstButton(); btn.Title = "我是主标题"; btn.SubTitle = "我是副标题"; btn.Content = new BitmapImage(new Uri("../../Resources/icon01.png", UriKind.Relative)) as ImageSource;
试着对代码进行修改:
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Windows; using System.Windows.Controls; using System.Windows.Data; using System.Windows.Documents; using System.Windows.Input; using System.Windows.Media; using System.Windows.Media.Imaging; using System.Windows.Navigation; using System.Windows.Shapes; namespace HordeElves { /// <summary> /// MyButton.xaml 的交互逻辑 /// </summary> public partial class MyFirstButton : UserControl { /// <summary> /// 按钮的主标题 /// </summary> public string Title { get { return this.title.Text; } set { this.title.Text = value; } } /// <summary> /// 按钮的副标题 /// </summary> public string SubTitle { get { return this.subtitle.Text; } set { this.subtitle.Text = value; } } /// <summary> /// 按钮的图片源 /// </summary> public ImageSource Source { get { return (ImageSource)this.btn.Content; } set { this.btn.Content = value; } } public MyFirstButton() { InitializeComponent(); } } }
以上是对几个特别的参数进行了封装,当我重新对Source属性赋值,就能够正常显示了。
btn = new MyFirstButton(); btn.Title = "我是主标题"; btn.SubTitle = "我是副标题"; btn.Source = new BitmapImage(new Uri("../../Resources/icon01.png", UriKind.Relative)) as ImageSource;
这里的问题在于,Xaml语句中Image的Source属性对应的是一个ImageSource对象,而Button的Content属性是一个object对象,修改的意义在于对其进行了兼容转换,这样Image的Source才能识别Content所含有的内容,记于此,供日后查证。