自己寫一個圖片按鈕(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
    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。

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


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM