天天看點

WPF學習-自定義控件庫!一、自定義控件庫流程(以添加圓角屬性為例)二、自定義ComboBox控件附件:學習過程中參考的文檔如下:

WPF自定義按鈕,增加圓角樣式功能!

  • 一、自定義控件庫流程(以添加圓角屬性為例)
    • 1.建立控件庫項目
    • 2.控件.cs檔案中添加邊框圓角屬性
    • 3.調用按鍵資源檔案
    • 4.編輯MyButton.xaml檔案,設定樣式
      • vs預設的樣式請參考:
      • 添加顔色資源
      • 設定預設樣式
      • 綁定邊框樣式資料
    • 5.完整MyButton.xaml資源字典如下:
    • 6.生成dll
    • 7.新項目調用
  • 二、自定義ComboBox控件
    • 1.自定義控件編輯模闆
    • 2.注意事項彙總
      • 自定義格式跨層級綁定外層控件的資料
      • 自定義下拉框樣式後出現綁定資料DisplayMemberPath屬性無效的情況
  • 附件:學習過程中參考的文檔如下:
    • 1.自定義控件流程

一、自定義控件庫流程(以添加圓角屬性為例)

1.建立控件庫項目

  1. 建立工程後,預設會有“Themes”檔案加,用于儲存控件樣式。
  2. 右鍵項目選擇添加建立項=> 選擇WPF => 選擇自定義控件(WPF)=> 輸入控件名然後電機添加,建立控件。
  3. 右鍵項目選擇添加資源字典(WPF)=> 輸入控件名然後電機添加,建立資源字典。
  4. 建立完畢後的架構如下圖:
    WPF學習-自定義控件庫!一、自定義控件庫流程(以添加圓角屬性為例)二、自定義ComboBox控件附件:學習過程中參考的文檔如下:

2.控件.cs檔案中添加邊框圓角屬性

public class MyButton : Button
    {
        static MyButton()
        {
            //                                              新建立的控件名                  模闆名,資源字典(如MyButton.xaml),如果要跟舊的一樣,直接填“Button”
            DefaultStyleKeyProperty.OverrideMetadata(typeof(MyButton), new FrameworkPropertyMetadata(typeof(MyButton)));
        }

        /// <summary>
        /// 按鍵圓角屬性委托
        /// CornerRadius:用于調用的委托名字
        /// typeof(MyButton):指定控件
        /// </summary>
        public static readonly DependencyProperty BorderRadiusProperty = DependencyProperty.Register("CornerRadius", typeof(int), typeof(MyButton), new FrameworkPropertyMetadata());

        /// <summary>
        /// 定義按鈕圓角屬性
        /// </summary>
        public int CornerRadius
        {
            get { return (int)GetValue(BorderRadiusProperty); }
            set { SetValue(BorderRadiusProperty, value); }
        }
    }
           

3.調用按鍵資源檔案

Generic.xaml中增加如下代碼,調用資源檔案MyButton.xaml

<ResourceDictionary.MergedDictionaries>
        <!--引用按鍵資源字典-->
        <ResourceDictionary Source= "/MyWpfCustomControlLibrary;Component/Themes/MyButton.xaml"/>
    </ResourceDictionary.MergedDictionaries>
           

4.編輯MyButton.xaml檔案,設定樣式

vs預設的樣式請參考:

Button 樣式和模闆

添加顔色資源

因為我将通用顔色

<!--引用顔色資源-->
    <ResourceDictionary.MergedDictionaries>
        <ResourceDictionary Source= "/MyWpfCustomControlLibrary;Component/Themes/ColorResource.xaml"/>
    </ResourceDictionary.MergedDictionaries>
           

設定預設樣式

//将設定預設添加時的樣式
    <Style TargetType="local:MyButton">
        <Setter Property="SnapsToDevicePixels" Value="true" />
        <Setter Property="FocusVisualStyle" Value="{StaticResource ButtonFocusVisual}" />
        <Setter Property="MinHeight" Value="23" />
        <Setter Property="MinWidth" Value="75" />
        //...後續代碼
           

綁定邊框樣式資料

在邊框屬性中,将邊框的屬性對控件屬性進行綁定

其中:

CornerRadius="{Binding Path=CornerRadius,RelativeSource={RelativeSource TemplatedParent}}",中的CornerRadius 對應.cs檔案中建立的委托名

其他屬性直接調用的控件原來就有的屬性

<Border TextBlock.Foreground="{TemplateBinding Foreground}"
                            x:Name="Border"
                            CornerRadius="{Binding Path=CornerRadius,RelativeSource={RelativeSource TemplatedParent}}"
                            Background="{TemplateBinding Background}"
                            BorderBrush="{TemplateBinding BorderBrush}"
                            BorderThickness="{TemplateBinding BorderThickness}">
                            //...
           

5.完整MyButton.xaml資源字典如下:

<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
                    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
                    xmlns:local="clr-namespace:MyWpfCustomControlLibrary"
                    xmlns:vsm="http://schemas.microsoft.com/netfx/2009/xaml/presentation">
   
    <!--引用顔色資源-->
    <ResourceDictionary.MergedDictionaries>
        <ResourceDictionary Source= "/MyWpfCustomControlLibrary;Component/Themes/ColorResource.xaml"/>
    </ResourceDictionary.MergedDictionaries>
    
    <!-- FocusVisual -->
    <Style x:Key="ButtonFocusVisual">
        <Setter Property="Control.Template">
            <Setter.Value>
                <ControlTemplate>
                    <Border>
                        <Rectangle Margin="2"
                         StrokeThickness="1"
                         Stroke="#60000000"
                         StrokeDashArray="1 2" />
                    </Border>
                </ControlTemplate>
            </Setter.Value>
        </Setter>
    </Style>

    <!-- Button -->
    <Style TargetType="local:MyButton">
        <Setter Property="SnapsToDevicePixels" Value="true" />
        <Setter Property="FocusVisualStyle" Value="{StaticResource ButtonFocusVisual}" />
        <Setter Property="MinHeight" Value="23" />
        <Setter Property="MinWidth" Value="75" />
        
        <Setter Property="Template">
            <Setter.Value>
                <ControlTemplate TargetType="Button">
                    <Grid>
                        <Border TextBlock.Foreground="{TemplateBinding Foreground}"
                            x:Name="Border"
                            CornerRadius="{Binding Path=CornerRadius,RelativeSource={RelativeSource TemplatedParent}}"
                            Background="{TemplateBinding Background}"
                            BorderBrush="{TemplateBinding BorderBrush}"
                            BorderThickness="{TemplateBinding BorderThickness}">

                            <VisualStateManager.VisualStateGroups>
                                <VisualStateGroup x:Name="CommonStates">
                                    <VisualStateGroup.Transitions>
                                        <VisualTransition GeneratedDuration="0:0:0.5" />
                                        <VisualTransition GeneratedDuration="0"
                                      To="Pressed" />
                                    </VisualStateGroup.Transitions>
                                    <VisualState x:Name="Normal" />
                                    <VisualState x:Name="MouseOver">
                                        <Storyboard>
                                            <ColorAnimationUsingKeyFrames Storyboard.TargetProperty="(Panel.Background).
                          (GradientBrush.GradientStops)[1].(GradientStop.Color)"
                                                    Storyboard.TargetName="Border">
                                                <EasingColorKeyFrame KeyTime="0"
                                             Value="{StaticResource ControlMouseOverColor}" />
                                            </ColorAnimationUsingKeyFrames>
                                        </Storyboard>
                                    </VisualState>
                                    <VisualState x:Name="Pressed">
                                        <Storyboard>
                                            <ColorAnimationUsingKeyFrames Storyboard.TargetProperty="(Panel.Background).
                          (GradientBrush.GradientStops)[1].(GradientStop.Color)"
                                                    Storyboard.TargetName="Border">
                                                <EasingColorKeyFrame KeyTime="0"
                                             Value="{StaticResource ControlPressedColor}" />
                                            </ColorAnimationUsingKeyFrames>
                                            <ColorAnimationUsingKeyFrames Storyboard.TargetProperty="(Border.BorderBrush).
                          (GradientBrush.GradientStops)[0].(GradientStop.Color)"
                                                    Storyboard.TargetName="Border">
                                                <EasingColorKeyFrame KeyTime="0"
                                             Value="{StaticResource PressedBorderDarkColor}" />
                                            </ColorAnimationUsingKeyFrames>
                                            <ColorAnimationUsingKeyFrames Storyboard.TargetProperty="(Border.BorderBrush).
                          (GradientBrush.GradientStops)[1].(GradientStop.Color)"
                                                    Storyboard.TargetName="Border">
                                                <EasingColorKeyFrame KeyTime="0"
                                             Value="{StaticResource PressedBorderLightColor}" />
                                            </ColorAnimationUsingKeyFrames>
                                        </Storyboard>
                                    </VisualState>
                                    <VisualState x:Name="Disabled">
                                        <Storyboard>
                                            <ColorAnimationUsingKeyFrames Storyboard.TargetProperty="(Panel.Background).
                          (GradientBrush.GradientStops)[1].(GradientStop.Color)"
                                                    Storyboard.TargetName="Border">
                                                <EasingColorKeyFrame KeyTime="0"
                                             Value="{StaticResource DisabledControlDarkColor}" />
                                            </ColorAnimationUsingKeyFrames>
                                            <ColorAnimationUsingKeyFrames
                          Storyboard.TargetProperty="(TextBlock.Foreground).(SolidColorBrush.Color)"
                                                    Storyboard.TargetName="Border">
                                                <EasingColorKeyFrame KeyTime="0"
                                             Value="{StaticResource DisabledForegroundColor}" />
                                            </ColorAnimationUsingKeyFrames>
                                            <ColorAnimationUsingKeyFrames Storyboard.TargetProperty="(Border.BorderBrush).
                          (GradientBrush.GradientStops)[1].(GradientStop.Color)"
                                                    Storyboard.TargetName="Border">
                                                <EasingColorKeyFrame KeyTime="0"
                                             Value="{StaticResource DisabledBorderDarkColor}" />
                                            </ColorAnimationUsingKeyFrames>
                                        </Storyboard>
                                    </VisualState>
                                </VisualStateGroup>
                            </VisualStateManager.VisualStateGroups>
                            <ContentPresenter Margin="2"
                                HorizontalAlignment="Center"
                                VerticalAlignment="Center"
                                RecognizesAccessKey="True" />
                        </Border>
                    </Grid>
                    
                    <ControlTemplate.Triggers>
                        <Trigger Property="IsDefault" Value="true">
                            <Setter TargetName="Border"  Property="BorderBrush">
                                <Setter.Value>
                                    <LinearGradientBrush StartPoint="0,0"  EndPoint="0,1">
                                        <GradientBrush.GradientStops>
                                            <GradientStopCollection>
                                                <GradientStop Color="{DynamicResource DefaultBorderBrushLightBrush}"  Offset="0.0" />
                                                <GradientStop Color="{DynamicResource DefaultBorderBrushDarkColor}"  Offset="1.0" />
                                            </GradientStopCollection>
                                        </GradientBrush.GradientStops>
                                    </LinearGradientBrush>
                                </Setter.Value>
                            </Setter>
                        </Trigger>
                    </ControlTemplate.Triggers>
                        
                </ControlTemplate>
            </Setter.Value>
        </Setter>
        
    </Style>

</ResourceDictionary>
           

6.生成dll

點選生成=> 選擇生成項目選項,生成

7.新項目調用

建立新項目,在新項目的引用項右鍵點選,添加引用

WPF學習-自定義控件庫!一、自定義控件庫流程(以添加圓角屬性為例)二、自定義ComboBox控件附件:學習過程中參考的文檔如下:

通過浏覽,找到生成的.dll檔案,然後将檔案添加到系統中,然後系統工具箱會自動顯示建立的控件,然後按照正常控件拖拽引用就可以。

WPF學習-自定義控件庫!一、自定義控件庫流程(以添加圓角屬性為例)二、自定義ComboBox控件附件:學習過程中參考的文檔如下:

拖拽引用後,xaml檔案中會自動添加調用資源:

二、自定義ComboBox控件

1.自定義控件編輯模闆

  • 組合框樣式:編輯ComboBoxStyle
  • 下拉框樣式:編輯ComboBoxItemStyle

2.注意事項彙總

自定義格式跨層級綁定外層控件的資料

使用查找綁定的方式綁定資料

自定義下拉框樣式後出現綁定資料DisplayMemberPath屬性無效的情況

這種情況是由于綁定格式時作為内容顯示的ContentPresenter沒有設定ContentTemplateSelector屬性引起的,綁定該屬性後解決問題

附件:學習過程中參考的文檔如下:

1.自定義控件流程

  • WPF自定義控件 按鈕 (一)
  • WPF 自定義TextBox帶水印控件,可設定圓角