你的位置:首页 > ASP.net教程

[ASP.net教程]自己写一个图片按钮(XAML)


有时需要用三张图片(正常状态,鼠标移上,鼠标按下)来作为一个按钮的样式,虽然这种做法不好,应该用矢量的方式制作样式,但有的时候还是需要这样做的。

每次都修改按钮的样式来实现这个做法,既麻烦又会生成大段的XAML代码,不利于维护,抽出一个自定义图片按钮控件,只需传入三张图片的路径即可使用,显然是更好的做法,下面就演示一下如何编写这个控件,VS2015和Blend2015结合使用。

1. 首先,在VS中新建一个WPF自定义控件库,命名为WpfCustomControlLibrary,系统会自动生成一个CustomControl1类,并生成一个Themes文件夹,其中包含一个资源字典文件Generic.xaml。如果打开AssemblyInfo.cs文件,会看到包含如下代码,

[assembly:ThemeInfo(  ResourceDictionaryLocation.None, //主题特定资源词典所处位置               //(在页面、应用程序或任何主题特定资源词典中               // 未找到某个资源的情况下使用)  ResourceDictionaryLocation.SourceAssembly //常规资源词典所处位置                   //(在页面、应用程序或任何主题特定资源词典中                   // 未找到某个资源的情况下使用))]

这段代码指明在Themes文件夹下的Generic.xaml资源字典中包含控件的默认样式,这正是WPF自定义控件库和一般程序集的区别。

2. 将CustomControl1类改为ImageButton

此时的初始代码如下,

  public class ImageButton : Control  {    static ImageButton()    {      DefaultStyleKeyProperty.OverrideMetadata(typeof(ImageButton), new FrameworkPropertyMetadata(typeof(ImageButton)));    }  }
<ResourceDictionary  ="http://schemas.microsoft.com/winfx/2006/xaml/presentation"  ="http://schemas.microsoft.com/winfx/2006/xaml"  ="clr-namespace:WpfCustomControlLibrary">  <Style TargetType="{x:Type local:ImageButton}">    <Setter Property="Template">      <Setter.Value>        <ControlTemplate TargetType="{x:Type local:ImageButton}">          <Border Background="{TemplateBinding Background}"              BorderBrush="{TemplateBinding BorderBrush}"              BorderThickness="{TemplateBinding BorderThickness}">          </Border>        </ControlTemplate>      </Setter.Value>    </Setter>  </Style></ResourceDictionary>

3. 把ImageButton的基类改为Button。

4. 在ImageButton中加入三个依赖属性,如下

    public static readonly DependencyProperty NormalImageProperty =      DependencyProperty.RegisterAttached("NormalImage", typeof(ImageSource), typeof(ImageButton), new PropertyMetadata(null));    public ImageSource NormalImage    {      get { return (ImageSource)GetValue(NormalImageProperty); }      set { SetValue(NormalImageProperty, value); }    }    public static readonly DependencyProperty MouseOverImageProperty =      DependencyProperty.RegisterAttached("MouseOverImage", typeof(ImageSource), typeof(ImageButton), new PropertyMetadata(null));    public ImageSource MouseOverImage    {      get { return (ImageSource)GetValue(MouseOverImageProperty); }      set { SetValue(MouseOverImageProperty, value); }    }    public static readonly DependencyProperty PressedImageProperty =      DependencyProperty.RegisterAttached("PressedImage", typeof(ImageSource), typeof(ImageButton), new PropertyMetadata(null));    public ImageSource PressedImage    {      get { return (ImageSource)GetValue(PressedImageProperty); }      set { SetValue(PressedImageProperty, value); }    }

5. 新建一个WPF应用程序项目引用该自定义控件库,在一个页面中,加入ImageButton控件。选中ImageButton控件,点击美工板导航栏中的[ImageButton],在弹出的菜单中选择编辑模板-编辑副本,在弹出的对话框中输入ImageButtonStyle,选择该文档,点击确定。

6. 在模板编辑状态下,右键点击文档大纲面板中的[Border],选择更改布局类型-Grid,然后将Grid的背景清空。向Grid中加入三个Image控件,并重置布局。可从资产面板加入,可在资产面板的搜索栏中输入Image查找。将三个Image的Width和Height清空,将Stretch属性改为None。

7. 将三个Image的Source属性从上到下分别改为模板绑定NormalImage,PressedImage和MouseOverImage,修改方法为在属性面板中点击Source属性右边的小方块,选择模板绑定-NormalImage。把PressedImage和MouseOverImage的Image的Visibility属性改为Collapsed。

8. 在状态面板中,点击MouseOver,在文档大纲面板中,选择第一个Image控件,在属性面板中,将Visibility属性改为Collapsed。选择第三个也就是MouseOverImage的Image控件,在属性面板中,将Visibility属性改为Visible。

在状态面板中,点击Pressed,在文档大纲面板中,选择第一个Image控件,在属性面板中,将Visibility属性改为Collapsed。选择第二个也就是PressedImage的Image控件,在属性面板中,将Visibility属性改为Visible。

此时ImageButtonStyle的代码如下,

<Style TargetType="{x:Type local:ImageButton}">    <Setter Property="Template">      <Setter.Value>        <ControlTemplate TargetType="{x:Type local:ImageButton}">          <Grid>            <VisualStateManager.VisualStateGroups>              <VisualStateGroup x:Name="CommonStates">                <VisualState x:Name="Normal"/>                <VisualState x:Name="MouseOver">                  <Storyboard>                    <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.Visibility)" Storyboard.TargetName="image">                      <DiscreteObjectKeyFrame KeyTime="0" Value="{x:Static Visibility.Collapsed}"/>                    </ObjectAnimationUsingKeyFrames>                    <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.Visibility)" Storyboard.TargetName="image1">                      <DiscreteObjectKeyFrame KeyTime="0" Value="{x:Static Visibility.Visible}"/>                    </ObjectAnimationUsingKeyFrames>                  </Storyboard>                </VisualState>                <VisualState x:Name="Pressed">                  <Storyboard>                    <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.Visibility)" Storyboard.TargetName="image">                      <DiscreteObjectKeyFrame KeyTime="0" Value="{x:Static Visibility.Collapsed}"/>                    </ObjectAnimationUsingKeyFrames>                    <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.Visibility)" Storyboard.TargetName="image2">                      <DiscreteObjectKeyFrame KeyTime="0" Value="{x:Static Visibility.Visible}"/>                    </ObjectAnimationUsingKeyFrames>                  </Storyboard>                </VisualState>                <VisualState x:Name="Disabled"/>              </VisualStateGroup>            </VisualStateManager.VisualStateGroups>            <Image x:Name="image" Source="{TemplateBinding NormalImage}" Stretch="None"/>            <Image x:Name="image2" Source="{TemplateBinding PressedImage}" Stretch="None" Visibility="Collapsed"/>            <Image x:Name="image1" Source="{TemplateBinding MouseOverImage}" Stretch="None" Visibility="Collapsed"/>          </Grid>        </ControlTemplate>      </Setter.Value>    </Setter>  </Style>

9. 用这个Style中的ControlTemple部分替换自定义控件库中的Themes文件夹下的Generic.xaml文件中的ImageButton样式的ControlTemple部分。注意修改TargetType为{x:Type local:ImageButton}"。

10. 这时图片按钮控件已经完成了,在WPF应用程序项目中的一个页面上,从资产面板中加入ImageButton控件(选择项目分类)。选择ImageButton控件,在属性面板中可以看到,在杂项组下,存在NormalImage,MouseOverImage和PressedImage三个属性,可分别设置图片。

11. 把这三个属性设置三张合适的图片,图片按钮即可使用。