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 Demo3.Control
{
public class ControlAttachProperty
{
#region 圆角 public static CornerRadius GetCornerRadius(DependencyObject obj)
{
return (CornerRadius)obj.GetValue(CornerRadiusProperty);
} public static void SetCornerRadius(DependencyObject obj, CornerRadius value)
{
obj.SetValue(CornerRadiusProperty, value);
} // Using a DependencyProperty as the backing store for CornerRadius. This enables animation, styling, binding, etc...
public static readonly DependencyProperty CornerRadiusProperty =
DependencyProperty.RegisterAttached("CornerRadius", typeof(CornerRadius), typeof(ControlAttachProperty), new PropertyMetadata(null)); #endregion #region 用户头像模板 public static ControlTemplate GetIconTemplate(DependencyObject obj)
{
return (ControlTemplate)obj.GetValue(IconTemplateProperty);
} public static void SetIconTemplate(DependencyObject obj, ControlTemplate value)
{
obj.SetValue(IconTemplateProperty, value);
} // Using a DependencyProperty as the backing store for IconTemplate. This enables animation, styling, binding, etc...
public static readonly DependencyProperty IconTemplateProperty =
DependencyProperty.RegisterAttached("IconTemplate", typeof(ControlTemplate), typeof(ControlAttachProperty), new PropertyMetadata(null)); #endregion #region 删除按妞区域模板 public static ControlTemplate GetAttachTemplate(DependencyObject obj)
{
return (ControlTemplate)obj.GetValue(AttachTemplateProperty);
} public static void SetAttachTemplate(DependencyObject obj, ControlTemplate value)
{
obj.SetValue(AttachTemplateProperty, value);
} // Using a DependencyProperty as the backing store for AttachTemplate. This enables animation, styling, binding, etc...
public static readonly DependencyProperty AttachTemplateProperty =
DependencyProperty.RegisterAttached("AttachTemplate", typeof(ControlTemplate), typeof(ControlAttachProperty), new PropertyMetadata(null)); #endregion #region 用户名水印 public static string GetUserNameWaterMark(DependencyObject obj)
{
return (string)obj.GetValue(UserNameWaterMarkProperty);
} public static void SetUserNameWaterMark(DependencyObject obj, string value)
{
obj.SetValue(UserNameWaterMarkProperty, value);
} // Using a DependencyProperty as the backing store for UserNameWaterMark. This enables animation, styling, binding, etc...
public static readonly DependencyProperty UserNameWaterMarkProperty =
DependencyProperty.RegisterAttached("UserNameWaterMark", typeof(string), typeof(ControlAttachProperty), new PropertyMetadata(null)); #endregion #region 密码水印 public static string GetPasswordWaterMark(DependencyObject obj)
{
return (string)obj.GetValue(PasswordWaterMarkProperty);
} public static void SetPasswordWaterMark(DependencyObject obj, string value)
{
obj.SetValue(PasswordWaterMarkProperty, value);
} // Using a DependencyProperty as the backing store for PasswordWaterMark. This enables animation, styling, binding, etc...
public static readonly DependencyProperty PasswordWaterMarkProperty =
DependencyProperty.RegisterAttached("PasswordWaterMark", typeof(string), typeof(ControlAttachProperty), new PropertyMetadata(null)); #endregion #region 用户头像(未被点击时) public static string GetUserIcon(DependencyObject obj)
{
return (string)obj.GetValue(UserIconProperty);
} public static void SetUserIcon(DependencyObject obj, string value)
{
obj.SetValue(UserIconProperty, value);
} // Using a DependencyProperty as the backing store for UserIcon. This enables animation, styling, binding, etc...
public static readonly DependencyProperty UserIconProperty =
DependencyProperty.RegisterAttached("UserIcon", typeof(string), typeof(ControlAttachProperty), new PropertyMetadata(null)); #endregion #region 用户头像(点击时) public static string GetUserIconPress(DependencyObject obj)
{
return (string)obj.GetValue(UserIconPressProperty);
} public static void SetUserIconPress(DependencyObject obj, string value)
{
obj.SetValue(UserIconPressProperty, value);
} // Using a DependencyProperty as the backing store for UserIconPress. This enables animation, styling, binding, etc...
public static readonly DependencyProperty UserIconPressProperty =
DependencyProperty.RegisterAttached("UserIconPress", typeof(string), typeof(ControlAttachProperty), new PropertyMetadata(null)); #endregion #region 密码图标(未被点击时) public static string GetPassWordIcon(DependencyObject obj)
{
return (string)obj.GetValue(PassWordIconProperty);
} public static void SetPassWordIcon(DependencyObject obj, string value)
{
obj.SetValue(PassWordIconProperty, value);
} // Using a DependencyProperty as the backing store for PassWordIcon. This enables animation, styling, binding, etc...
public static readonly DependencyProperty PassWordIconProperty =
DependencyProperty.RegisterAttached("PassWordIcon", typeof(string), typeof(ControlAttachProperty), new PropertyMetadata(null)); #endregion #region 密码图标(点击时) public static string GetPasswordIconPress(DependencyObject obj)
{
return (string)obj.GetValue(PasswordIconPressProperty);
} public static void SetPasswordIconPress(DependencyObject obj, string value)
{
obj.SetValue(PasswordIconPressProperty, value);
} // Using a DependencyProperty as the backing store for PasswordIconPress. This enables animation, styling, binding, etc...
public static readonly DependencyProperty PasswordIconPressProperty =
DependencyProperty.RegisterAttached("PasswordIconPress", typeof(string), typeof(ControlAttachProperty), new PropertyMetadata(null)); #endregion #region 删除按妞背景图片 public static ImageBrush GetDeleteButtonBG(DependencyObject obj)
{
return (ImageBrush)obj.GetValue(DeleteButtonBGProperty);
} public static void SetDeleteButtonBG(DependencyObject obj, ImageBrush value)
{
obj.SetValue(DeleteButtonBGProperty, value);
} // Using a DependencyProperty as the backing store for DeleteButtonBG. This enables animation, styling, binding, etc...
public static readonly DependencyProperty DeleteButtonBGProperty =
DependencyProperty.RegisterAttached("DeleteButtonBG", typeof(ImageBrush), typeof(ControlAttachProperty), new PropertyMetadata(null)); #endregion #region 定义是否开启绑定事件 public static bool GetIsCommandClearTextEvent(DependencyObject obj)
{
return (bool)obj.GetValue(IsCommandClearTextEventProperty);
} public static void SetIsCommandClearTextEvent(DependencyObject obj, bool value)
{
obj.SetValue(IsCommandClearTextEventProperty, value);
} // Using a DependencyProperty as the backing store for IsCommandClearTextEvent. This enables animation, styling, binding, etc...
public static readonly DependencyProperty IsCommandClearTextEventProperty =
DependencyProperty.RegisterAttached("IsCommandClearTextEvent", typeof(bool), typeof(ControlAttachProperty), new FrameworkPropertyMetadata(false,IsCommandClearTextEventChanged)); private static void IsCommandClearTextEventChanged(DependencyObject d,DependencyPropertyChangedEventArgs e)
{ }
#endregion #region 是否显示密码样式 public static bool GetIsVisiblityPassword(DependencyObject obj)
{
return (bool)obj.GetValue(IsVisiblityPasswordProperty);
} public static void SetIsVisiblityPassword(DependencyObject obj, bool value)
{
obj.SetValue(IsVisiblityPasswordProperty, value);
} // Using a DependencyProperty as the backing store for IsVisiblityPassword. This enables animation, styling, binding, etc...
public static readonly DependencyProperty IsVisiblityPasswordProperty =
DependencyProperty.RegisterAttached("IsVisiblityPassword", typeof(bool), typeof(ControlAttachProperty), new PropertyMetadata(false)); #endregion #region 清除事件命令 public static bool GetIsClearTextButtonBehaviorEnabled(DependencyObject obj)
{
return (bool)obj.GetValue(IsClearTextButtonBehaviorEnabledProperty);
} public static void SetIsClearTextButtonBehaviorEnabled(DependencyObject obj, bool value)
{
obj.SetValue(IsClearTextButtonBehaviorEnabledProperty, value);
} // Using a DependencyProperty as the backing store for IsClearTextButtonBehaviorEnabled. This enables animation, styling, binding, etc...
public static readonly DependencyProperty IsClearTextButtonBehaviorEnabledProperty =
DependencyProperty.RegisterAttached("IsClearTextButtonBehaviorEnabled", typeof(bool), typeof(ControlAttachProperty), new FrameworkPropertyMetadata(false,IsClearTextButtonBehaviorEnabledChanged)); /// <summary>
/// 当附加属性值发生改变时,调用此方法
/// </summary>
/// <param name="d"></param>
/// <param name="e"></param>
private static void IsClearTextButtonBehaviorEnabledChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
var button=d as DeleteButton;
if(e.OldValue != e.NewValue)
{
//当命令触发的时候,会向上传递,而此时这个命令外围就是自己本身
button.CommandBindings.Add(ClearTextCommandBinding);
}
} /**
* 当命令触发的时候,会一级一级向上传递,当传递到命令关联者时,会处理这个命令
*/ /// <summary>
/// 创建一个命令
/// </summary>
public static RoutedUICommand ClearTextCommand{get;private set;} /// <summary>
/// 命令绑定关联
/// </summary>
private static readonly CommandBinding ClearTextCommandBinding; private static void ClearButtonClick(object sender,ExecutedRoutedEventArgs e)
{
var tbox=e.Parameter as FrameworkElement;
if(tbox==null) return;
if(tbox is TextBox)
{
((TextBox)tbox).Clear();
} tbox.Focus();
} #endregion static ControlAttachProperty()
{
ClearTextCommand = new RoutedUICommand(); ClearTextCommandBinding =new CommandBinding();
//将者命令加入到这个命令关联中,如果某个控件调用了这个命令,只要他所在的层级中有关联这个命令关联对象,那么这个命令对象就会对其进行处理
ClearTextCommandBinding.Command = ClearTextCommand;
ClearTextCommandBinding.Executed+=ClearButtonClick;
}
}
}
在布局文件中使用它
<Window x:Class="Demo3.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:c="clr-namespace:Demo3.Control"
Background="Black"
Title="MainWindow"
WindowStartupLocation="CenterScreen"
Height="350"
Width="525"> <StackPanel>
<TextBox x:Name="UserName"
Width="230"
Height="38"
Margin="0,20,0,0"
FontSize="18"
VerticalContentAlignment="Center"
c:ControlAttachProperty.CornerRadius="5"
c:ControlAttachProperty.UserNameWaterMark="用户名"
c:ControlAttachProperty.UserIcon="{StaticResource UserName_BG}"
c:ControlAttachProperty.UserIconPress="{StaticResource UserName_BG_Press}"
c:ControlAttachProperty.DeleteButtonBG="{StaticResource Delete_Button_BG}"
c:ControlAttachProperty.IsVisiblityPassword="false"
Style="{StaticResource IconClearButtonTextBox}" /> <TextBox x:Name="Password"
Width="230"
Height="38"
Margin="0,20,0,0"
FontSize="18"
VerticalContentAlignment="Center"
c:ControlAttachProperty.CornerRadius="5"
c:ControlAttachProperty.UserNameWaterMark="密码"
c:ControlAttachProperty.UserIcon="{StaticResource Password_BG}"
c:ControlAttachProperty.UserIconPress="{StaticResource Password_BG_Press}"
c:ControlAttachProperty.DeleteButtonBG="{StaticResource Delete_Button_BG}"
c:ControlAttachProperty.IsVisiblityPassword="true"
Style="{StaticResource IconClearButtonTextBox}" />
</StackPanel> </Window>
在style文件中进行使用
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:c="clr-namespace:Demo3.Control"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"> <ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="/Demo3;component/Resources/Style/DeleteButton.xaml" />
</ResourceDictionary.MergedDictionaries> <!--TextBox默认样式-->
<Style x:Key="DefaultTextBox" TargetType="{x:Type TextBox}">
<Setter Property="ContextMenu" Value="{DynamicResource TextBoxContextMenu}" />
<Setter Property="VerticalContentAlignment" Value="Center" />
<Setter Property="SnapsToDevicePixels" Value="True" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type TextBox}">
<Border x:Name="Bg"
SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}"
CornerRadius="{TemplateBinding c:ControlAttachProperty.CornerRadius}"
Background="White"
BorderBrush="Transparent"
BorderThickness="0">
<Grid x:Name="PART_InnerGrid">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="30"/>
<ColumnDefinition />
<ColumnDefinition Width="40"/>
</Grid.ColumnDefinitions> <!--用户头像区域-->
<ContentControl x:Name="UserIcon"
Grid.Column="0"
Margin="5"
Template="{TemplateBinding c:ControlAttachProperty.IconTemplate}"
Focusable="False" /> <!--文本和水印-->
<ScrollViewer x:Name="PART_ContentHost"
BorderThickness="0"
Grid.Column="1"
IsTabStop="False"
Margin="2"
VerticalAlignment="Stretch"
Background="{x:Null}" />
<TextBlock x:Name="WaterMark"
Grid.Column="1"
VerticalAlignment="Center"
Foreground="Silver"
FontSize="18"
Text="{TemplateBinding c:ControlAttachProperty.UserNameWaterMark}"
Visibility="Collapsed"
Padding="5,0,0,0" /> <!-- 删除按钮-->
<ContentControl x:Name="DeleteIcon"
Grid.Column="2"
Width="15"
Height="15"
Margin="0,5,10,5"
Visibility="Visible"
VerticalAlignment="Center"
HorizontalAlignment="Right"
Template="{TemplateBinding c:ControlAttachProperty.AttachTemplate}"
Focusable="False" />
</Grid>
</Border> <ControlTemplate.Triggers>
<!--当Text为空时,隐藏删除按钮-->
<DataTrigger Binding="{Binding RelativeSource={RelativeSource Self},Path=Text}" Value="">
<Setter Property="Visibility" TargetName="DeleteIcon" Value="Collapsed" />
<Setter Property="Visibility" TargetName="WaterMark" Value="Visible" />
</DataTrigger> <!--是否显示密码样式-->
<Trigger Property="c:ControlAttachProperty.IsVisiblityPassword" Value="True">
<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> <!--TextBox包含附加属性Icon,以及ClearText按钮的样式-->
<Style x:Key="IconClearButtonTextBox" TargetType="{x:Type TextBox}" BasedOn="{StaticResource DefaultTextBox}">
<!--设置用户头像模板-->
<Setter Property="c:ControlAttachProperty.IconTemplate">
<Setter.Value>
<ControlTemplate TargetType="ContentControl">
<Grid>
<Image x:Name="Bg_HP"
Source="{Binding Path=(c:ControlAttachProperty.UserIcon),RelativeSource={RelativeSource Mode=FindAncestor,AncestorType={x:Type TextBox}}}"
Visibility="Visible"/>
<Image x:Name="Bg_HP_Press"
Source="{Binding Path=(c:ControlAttachProperty.UserIconPress),RelativeSource={RelativeSource Mode=FindAncestor,AncestorType={x:Type TextBox}}}"
Visibility="Collapsed" />
</Grid> <ControlTemplate.Triggers>
<DataTrigger Binding="{Binding IsFocused, RelativeSource={RelativeSource FindAncestor,AncestorType={x:Type TextBox}}}" Value="true">
<Setter Property="Visibility" TargetName="Bg_HP" Value="Collapsed" />
<Setter Property="Visibility" TargetName="Bg_HP_Press" Value="Visible" />
</DataTrigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter> <!--设置删除按妞模板-->
<Setter Property="c:ControlAttachProperty.AttachTemplate">
<Setter.Value>
<ControlTemplate TargetType="ContentControl">
<c:DeleteButton ButtonBG="{Binding Path=(c:ControlAttachProperty.DeleteButtonBG),RelativeSource={RelativeSource Mode=FindAncestor,AncestorType={x:Type TextBox}}}"
BorderBrush="Transparent"
Style="{StaticResource DeleteButtonStyle}"
BorderThickness="0"
x:Name="CleanButton"
c:ControlAttachProperty.IsClearTextButtonBehaviorEnabled="True"
Command="c:ControlAttachProperty.ClearTextCommand"
CommandParameter="{Binding RelativeSource={RelativeSource FindAncestor,AncestorType={x:Type TextBox}}}"
Focusable="false" /> <ControlTemplate.Triggers>
<DataTrigger Binding="{Binding Text,RelativeSource={RelativeSource FindAncestor,AncestorType={x:Type TextBox}}}" Value="">
<Setter Property="Visibility" TargetName="CleanButton" Value="Collapsed" />
</DataTrigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</ResourceDictionary>
WPF 使用附加属性增加控件属性的更多相关文章
- WPF利用通过父控件属性来获得绑定数据源RelativeSource
WPF利用通过父控件属性来获得绑定数据源RelativeSource 有时候我们不确定作为数据源的对象叫什么名字,但知道作为绑定源与UI布局有相对的关系,如下是一段XAML代码,说明多层布局控件中 ...
- WPF Adorner+附加属性 实现控件友好提示
标题太空泛,直接上图 无论是在验证啊,还是提示方面等一些右上角的角标之类的效果,我们会怎么做? 这里介绍一种稍微简单一些的方法,利用附加属性和Adorner来完成. 例如WPF自带的控件上要加这样的效 ...
- WPF编程,通过Double Animation动态更改控件属性的一种方法。
原文:WPF编程,通过Double Animation动态更改控件属性的一种方法. 版权声明:我不生产代码,我只是代码的搬运工. https://blog.csdn.net/qq_43307934/a ...
- WPF编程,通过【帧】动态更改控件属性的一种方法。
原文:WPF编程,通过[帧]动态更改控件属性的一种方法. 版权声明:我不生产代码,我只是代码的搬运工. https://blog.csdn.net/qq_43307934/article/detail ...
- WPF学习- AllowDrop 用户控件启用拖放功能
知识点: 创建自定义用户控件(UserControl) 使用户控件成为拖动源 使用户控件成为放置目标 使面板能够接收从用户控件放置的数据 创建项目: 1.新建WPF项目(Wpf-AllowDrop) ...
- WPF 精修篇 用户控件
原文:WPF 精修篇 用户控件 增加用户控件 数据绑定还是用依赖属性 使用的事件 就委托注册一下 public delegate void ButtonClick(object b,EventArgs ...
- 在WPF中使用WinForm控件方法
1. 首先添加对如下两个dll文件的引用:WindowsFormsIntegration.dll,System.Windows.Forms.dll. 2. 在要使用WinForm控 ...
- ExtJs控件属性配置详细
序言: 1.本文摘自网络,看控件命名像是4.0以前的版本,但控件属性配置仍然可以借鉴(不足之处,以后项目用到时再续完善). Ext.form.TimeField: 配置项: ...
- WPF中的image控件的Source赋值
WPF中的Image控件Source的设置 1.XAML中 简单的方式(Source="haha.png"); image控件的Source设置为相对路径后(Source=&quo ...
随机推荐
- .net图表之ECharts随笔08-bar柱状图
之前一直都是跟着修改demo,感觉用得很吃力,现在结合上配置手册就好很多了,其实说到底就是参数的配置,所以配置手册尤为重要. 当然,这其中还是很多坑,希望可以找到对应的解决方案吧!!! 1. tool ...
- TOJ1398正方形的编成 或者 POJ2362
#include<stdio.h> #include<string.h> #include<iostream> #include<algorithm> ...
- Java50道经典习题-程序18 乒乓球赛
题目:两个乒乓球队进行比赛,各出三人.甲队为a,b,c三人,乙队为x,y,z三人.已抽签决定比赛名单.有人向队员打听比赛的名单. a说他不和x比,c说他不和x,z比,请编程序找出三队赛手的名单.分析: ...
- 1087 1 10 100 1000(打表 set 数学)
1087 1 10 100 1000 题目来源: Ural 1209 基准时间限制:1 秒 空间限制:131072 KB 分值: 5 难度:1级算法题 收藏 关注 1,10,100,1000... ...
- G - 確率(水题)
原文链接 G - 確率 Time Limit:1000MS Memory Limit:131072KB 64bit IO Format:%lld & %llu Submit S ...
- ObjectARX动态添加AutoCAD传统下拉菜单入门篇(一)
ObjectARX动态添加传统下拉菜单入门篇 图文by edata , 转载注明出处 http://www.cnblogs.com/edata AutoCAD 添加传统下拉菜单有很多种方式,比较典型 ...
- Java8新特性学习笔记(一) Lambda表达式
没有用Lambda表达式的写法: Comparator<Transaction> byYear = new Comparator<Transaction>() { @Overr ...
- 查看inux系统类型和版本
当我们使用一台新的linux服务器的时候,为了区分他们的命令,我们首先第一步就是要搞清楚这个系统的类型和版本号,据此再来使用对应的命令. 下面来看看可以使用以下基本命令来查看 Linux 发行版名称和 ...
- 爬虫实战4:用selenium爬取淘宝美食
方案1:一次性爬取全部淘宝美食信息 1. spider.py文件如下 __author__ = 'Administrator' from selenium import webdriver from ...
- 实例的初始化由JVM装载类的时候进行,保证了线程的安全性
在23种设计模式中,单例是最简单的设计模式,但是也是很常用的设计模式.从单例的五种实现方式中我们可以看到程序员对性能的不懈追求.下面我将分析单例的五种实现方式的优缺点,并对其在多线程环境下的性能进行测 ...