日期:2014-06-10  浏览次数:20533 次

最近在捣鼓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所含有的内容,记于此,供日后查证。