WPF自定義按鈕,增加圓角樣式功能!
- 一、自定義控件庫流程(以添加圓角屬性為例)
-
- 1.建立控件庫項目
- 2.控件.cs檔案中添加邊框圓角屬性
- 3.調用按鍵資源檔案
- 4.編輯MyButton.xaml檔案,設定樣式
-
- vs預設的樣式請參考:
- 添加顔色資源
- 設定預設樣式
- 綁定邊框樣式資料
- 5.完整MyButton.xaml資源字典如下:
- 6.生成dll
- 7.新項目調用
- 二、自定義ComboBox控件
-
- 1.自定義控件編輯模闆
- 2.注意事項彙總
-
- 自定義格式跨層級綁定外層控件的資料
- 自定義下拉框樣式後出現綁定資料DisplayMemberPath屬性無效的情況
- 附件:學習過程中參考的文檔如下:
-
- 1.自定義控件流程
一、自定義控件庫流程(以添加圓角屬性為例)
1.建立控件庫項目
- 建立工程後,預設會有“Themes”檔案加,用于儲存控件樣式。
- 右鍵項目選擇添加建立項=> 選擇WPF => 選擇自定義控件(WPF)=> 輸入控件名然後電機添加,建立控件。
- 右鍵項目選擇添加資源字典(WPF)=> 輸入控件名然後電機添加,建立資源字典。
- 建立完畢後的架構如下圖:
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.新項目調用
建立新項目,在新項目的引用項右鍵點選,添加引用
通過浏覽,找到生成的.dll檔案,然後将檔案添加到系統中,然後系統工具箱會自動顯示建立的控件,然後按照正常控件拖拽引用就可以。
拖拽引用後,xaml檔案中會自動添加調用資源:
二、自定義ComboBox控件
1.自定義控件編輯模闆
- 組合框樣式:編輯ComboBoxStyle
- 下拉框樣式:編輯ComboBoxItemStyle
2.注意事項彙總
自定義格式跨層級綁定外層控件的資料
使用查找綁定的方式綁定資料
自定義下拉框樣式後出現綁定資料DisplayMemberPath屬性無效的情況
這種情況是由于綁定格式時作為内容顯示的ContentPresenter沒有設定ContentTemplateSelector屬性引起的,綁定該屬性後解決問題
附件:學習過程中參考的文檔如下:
1.自定義控件流程
- WPF自定義控件 按鈕 (一)
- WPF 自定義TextBox帶水印控件,可設定圓角