WPF 使用依赖属性自定义控件
使用依赖属性自定义控件,依赖属性必须定义在自定义控件中,不能定义在其他文件中
一、先实现一个类继承你要复写的类
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Windows; using System.Windows.Controls; using System.Windows.Input; using System.Windows.Media; namespace Demo2.Controls { public class UserNameBox : TextBox { #region 用户名图标 public string Icon { get { return (string)GetValue(IconProperty); } set { SetValue(IconProperty, value); } } // Using a DependencyProperty as the backing store for Icon. This enables animation, styling, binding, etc... public static readonly DependencyProperty IconProperty = DependencyProperty.Register("Icon", typeof(string), typeof(UserNameBox)); #endregion #region 获取焦点时,用户名图标 public string Focused_Icon { get { return (string)GetValue(Focused_IconProperty); } set { SetValue(Focused_IconProperty, value); } } // Using a DependencyProperty as the backing store for Focused_Icon. This enables animation, styling, binding, etc... public static readonly DependencyProperty Focused_IconProperty = DependencyProperty.Register("Focused_Icon", typeof(string), typeof(UserNameBox)); #endregion #region 水印内容 public string WaterMark { get { return (string)GetValue(WaterMarkProperty); } set { SetValue(WaterMarkProperty, value); } } // Using a DependencyProperty as the backing store for WaterMark. This enables animation, styling, binding, etc... public static readonly DependencyProperty WaterMarkProperty = DependencyProperty.Register("WaterMark", typeof(string), typeof(UserNameBox)); #endregion #region 圆角大小 public double CornerRadius { get { return (double)GetValue(CornerRadiusProperty); } set { SetValue(CornerRadiusProperty, value); } } // Using a DependencyProperty as the backing store for CornerRadius. This enables animation, styling, binding, etc... public static readonly DependencyProperty CornerRadiusProperty = DependencyProperty.Register("CornerRadius", typeof(double), typeof(UserNameBox)); #endregion #region 删除按钮 public ImageBrush DeleteIcon { get { return (ImageBrush)GetValue(DeleteIconProperty); } set { SetValue(DeleteIconProperty, value); } } // Using a DependencyProperty as the backing store for DeleteIcon. This enables animation, styling, binding, etc... public static readonly DependencyProperty DeleteIconProperty = DependencyProperty.Register("DeleteIcon", typeof(ImageBrush), typeof(UserNameBox)); #endregion #region 是否显示密码框 public bool IsVisiblityPassword { get { return (bool)GetValue(IsVisiblityPasswordProperty); } set { SetValue(IsVisiblityPasswordProperty, value); } } // Using a DependencyProperty as the backing store for IsVisiblityPassword. This enables animation, styling, binding, etc... public static readonly DependencyProperty IsVisiblityPasswordProperty = DependencyProperty.Register("IsVisiblityPassword", typeof(bool), typeof(UserNameBox)); #endregion } }
在里面定义的依赖属性就为你自定义控件的属性,可以在布局文件中使用它们来进行设定值
可以在布局中设定值,然后在style中进行引用
<Window x:Class="Demo2.MainWindow" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:c="clr-namespace:Demo2.Controls" xmlns:s="clr-namespace:System;assembly=mscorlib" Background="Black" WindowStartupLocation="CenterScreen" Title="Demo2" Height="300" Width="300"> <Window.Resources> <s:String x:Key="Username_Unclick">/Demo2;component/Resources/Icons/username_unclick.png</s:String> <s:String x:Key="Username_Onclick">/Demo2;component/Resources/Icons/username_onclick.png</s:String> <s:String x:Key="Password_Unclick">/Demo2;component/Resources/Icons/password_unclick.png</s:String> <s:String x:Key="Password_Onclick">/Demo2;component/Resources/Icons/password_onclick.png</s:String> <ImageBrush x:Key="Delete_Icon" ImageSource="/Demo2;component/Resources/Icons/delete.png" /> </Window.Resources> <StackPanel> <!--用户名--> <c:UserNameBox Width="230" Height="38" Margin="0,20,0,0" FontSize="18" Text="{Binding UserName,Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}" VerticalContentAlignment="Center" WaterMark="用户名" CornerRadius="5" DeleteIcon="{StaticResource Delete_Icon}" Icon="{StaticResource Username_Unclick}" IsVisiblityPassword="False" Focused_Icon="{StaticResource Username_Onclick}"/> <!--密码--> <c:UserNameBox x:Name="password" Width="230" Height="38" Margin="0,20,0,0" FontSize="18" Text="{Binding Password,Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}" VerticalContentAlignment="Center" WaterMark="密码" CornerRadius="5" IsVisiblityPassword="True" DeleteIcon="{StaticResource Delete_Icon}" Icon="{StaticResource Password_Unclick}" Focused_Icon="{StaticResource Password_Onclick}"/> </StackPanel> </Window>
在style中进行引用
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:c="clr-namespace:Demo2.Controls" xmlns:i="http://schemas.microsoft.com/expression/2010/interactivity" xmlns:Themes="clr-namespace:Microsoft.Windows.Themes;assembly=PresentationFramework.Aero" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"> <Style TargetType="{x:Type c:UserNameBox}"> <Setter Property="Foreground" Value="{DynamicResource {x:Static SystemColors.ControlTextBrushKey}}"/> <Setter Property="Background" Value="{x:Null}"/> <Setter Property="BorderThickness" Value="1"/> <Setter Property="Padding" Value="1"/> <Setter Property="AllowDrop" Value="true"/> <Setter Property="FocusVisualStyle" Value="{x:Null}"/> <Setter Property="ScrollViewer.PanningMode" Value="VerticalFirst"/> <Setter Property="Stylus.IsFlicksEnabled" Value="False"/> <Setter Property="Template"> <Setter.Value> <ControlTemplate TargetType="{x:Type c:UserNameBox}"> <Border Background="White" BorderThickness="0" CornerRadius="{Binding RelativeSource={RelativeSource TemplatedParent},Path=CornerRadius}"> <Grid> <!--分为3列--> <Grid.ColumnDefinitions> <ColumnDefinition Width="30"/> <ColumnDefinition/> <ColumnDefinition Width="40"/> </Grid.ColumnDefinitions> <!--图标--> <Image Grid.Column="0" Margin="5,0,5,0" x:Name="usernameIcon" Source="{Binding RelativeSource={RelativeSource TemplatedParent},Path=Icon}" /> <!--文本和水印--> <ScrollViewer Grid.Column="1" x:Name="PART_ContentHost" SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" Focusable="True"/> <TextBlock x:Name="waterMark" Grid.Column="1" VerticalAlignment="Center" Foreground="Silver" FontSize="18" Padding="5,0,0,0" /> <!--删除按钮--> <c:DeleteButton x:Name="deleteTextButton" Grid.Column="2" Width="15" Height="15" Style="{DynamicResource ButtonStyle2}" ButtonBG="{Binding RelativeSource={RelativeSource TemplatedParent},Path=DeleteIcon}" Margin="0,5,10,5" Visibility="Visible" VerticalAlignment="Center" HorizontalAlignment="Right" Focusable="False" Command="{Binding CleanUserNameCommand}"/> </Grid> </Border> <ControlTemplate.Triggers> <!--当获取焦点时--> <Trigger Property="IsFocused" Value="true"> <Setter Property="Source" TargetName="usernameIcon" Value="{Binding RelativeSource={RelativeSource TemplatedParent},Path=Focused_Icon}" /> </Trigger> <!--当文本为空时--> <Trigger Property="Text" Value=""> <Setter Property="Text" TargetName="waterMark" Value="{Binding RelativeSource={RelativeSource TemplatedParent},Path=WaterMark}" /> <Setter Property="Visibility" TargetName="deleteTextButton" Value="Collapsed" /> </Trigger> <!--当属性为true时,显示密码框(将文本显示格式更改位密码显示样式)--> <Trigger Property="IsVisiblityPassword" Value="true"> <Setter Property="Command" TargetName="deleteTextButton" Value="{Binding CleanPasswordCommand}" /> <Setter Property="Height" Value="30"/> <Setter Property="Foreground" Value="Transparent"></Setter> <Setter Property="FontSize" Value="20"></Setter> <Setter Property="FontFamily" Value="Courier New"></Setter> <Setter Property="TextDecorations"> <Setter.Value> <TextDecorationCollection> <TextDecoration> <TextDecoration.Pen> <Pen Thickness="10" Brush="Black" EndLineCap="Round" StartLineCap="Round" DashCap="Round" > <Pen.DashStyle> <DashStyle Dashes="0.0,1.2" Offset="0.6"/> </Pen.DashStyle> </Pen> </TextDecoration.Pen> <TextDecoration.Location> <TextDecorationLocation>Strikethrough</TextDecorationLocation> </TextDecoration.Location> </TextDecoration> </TextDecorationCollection> </Setter.Value> </Setter> </Trigger> </ControlTemplate.Triggers> </ControlTemplate> </Setter.Value> </Setter> </Style> </ResourceDictionary>