本身寫一個圖片按鈕(XAML)

有時須要用三張圖片(正常狀態,鼠標移上,鼠標按下)來做爲一個按鈕的樣式,雖然這種作法很差,應該用矢量的方式製做樣式,但有的時候仍是須要這樣作的。html

每次都修改按鈕的樣式來實現這個作法,既麻煩又會生成大段的XAML代碼,不利於維護,抽出一個自定義圖片按鈕控件,只需傳入三張圖片的路徑便可使用,顯然是更好的作法,下面就演示一下如何編寫這個控件,VS2015和Blend2015結合使用。ide

1. 首先,在VS中新建一個WPF自定義控件庫,命名爲WpfCustomControlLibrary,系統會自動生成一個CustomControl1類,並生成一個Themes文件夾,其中包含一個資源字典文件Generic.xaml。若是打開AssemblyInfo.cs文件,會看到包含以下代碼,佈局

[assembly:ThemeInfo(
    ResourceDictionaryLocation.None, //主題特定資源詞典所處位置
                             //(在頁面、應用程序或任何主題特定資源詞典中
                             // 未找到某個資源的狀況下使用)
    ResourceDictionaryLocation.SourceAssembly //常規資源詞典所處位置
                                      //(在頁面、應用程序或任何主題特定資源詞典中
                                      // 未找到某個資源的狀況下使用)
)]

這段代碼指明在Themes文件夾下的Generic.xaml資源字典中包含控件的默認樣式,這正是WPF自定義控件庫和通常程序集的區別。spa

2. 將CustomControl1類改成ImageButtoncode

此時的初始代碼以下,orm

    public class ImageButton : Control
    {
        static ImageButton()
        {
            DefaultStyleKeyProperty.OverrideMetadata(typeof(ImageButton), new FrameworkPropertyMetadata(typeof(ImageButton)));
        }
    }
<ResourceDictionary
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:local="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。xml

4. 在ImageButton中加入三個依賴屬性,以下htm

        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,選擇該文檔,點擊肯定。blog

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. 把這三個屬性設置三張合適的圖片,圖片按鈕便可使用。

相關文章
相關標籤/搜索