zoukankan      html  css  js  c++  java
  • 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>
    

      

  • 相关阅读:
    Java秒杀系统实战系列~整合RabbitMQ实现消息异步发送
    Java秒杀系统实战系列~分布式唯一ID生成订单编号
    Java秒杀系统实战系列~商品秒杀代码实战
    Java秒杀系统实战系列~整合Shiro实现用户登录认证
    Java秒杀系统实战系列~待秒杀商品列表与详情功能开发
    Java秒杀系统实战系列~整体业务流程介绍与数据库设计
    Java秒杀系统实战系列~构建SpringBoot多模块项目
    重磅发布- Java秒杀系统的设计与实战视频教程(SpringBoot版)
    ct
    mysql 分区表
  • 原文地址:https://www.cnblogs.com/callyblog/p/7519262.html
Copyright © 2011-2022 走看看