• WPF中依赖属性及附加属性的概念及用法


    完全来源于十月的寒流,感谢大佬讲解

    依赖属性

    在这里插入图片描述

    由依赖属性提供的属性功能
    与字段支持的属性不同,依赖属性扩展了属性的功能。 通常,添加的功能表示或支持以下功能之一:

    • 资源
    • 数据绑定
    • 样式
    • 动画
    • 元数据重写
    • 属性值继承
    • WPF 设计器集成
        public partial class MainWindow : Window
        {
            public MainWindow()
            {
                InitializeComponent();
                CustomTextBox customTextBox = new CustomTextBox();
                customTextBox.IsHightLighted = true;
    
                customTextBox.SetValue(CustomTextBox.IsHightLightedProperty, true);
            }
        }
    
        public class CustomTextBox : TextBox
        {
            public bool IsHightLighted
            {
                get { return (bool)GetValue(IsHightLightedProperty); }
                set { SetValue(IsHightLightedProperty, value); }
            }
    
            public static readonly DependencyProperty IsHightLightedProperty =
                DependencyProperty.Register("IsHightLighted", typeof(bool), typeof(CustomTextBox), new PropertyMetadata(false));
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    #region HasText
    public bool HasText => (bool)GetValue(HasTextProperty);
    
    public static readonly DependencyProperty HasTextProperty;
    public static readonly DependencyPropertyKey HasTextPropertyKey;
    
    static CustomTextBox()
    {
        HasTextPropertyKey = DependencyProperty.RegisterReadOnly(
            "HasText",
            typeof(bool),
            typeof(CustomTextBox),
            new PropertyMetadata(false)
            );
        HasTextProperty = HasTextPropertyKey.DependencyProperty;
    }
    #endregion
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    <Window x:Class="Test_05.MainWindow"
            xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
            xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
            xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
            xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
            xmlns:local="clr-namespace:Test_05"
            mc:Ignorable="d"
            Title="MainWindow" Height="450" Width="800">
    
        <Window.Resources>
            <Style TargetType="local:CustomTextBox">
                <Style.Triggers>
                    <Trigger Property="IsHightLighted" Value="True">
                        <Setter Property="Background" Value="Yellow"></Setter>
                    </Trigger>
                    <Trigger Property="IsHightLighted" Value="False">
                        <Setter Property="Background" Value="Blue"></Setter>
                    </Trigger>
                </Style.Triggers>
            </Style>
        </Window.Resources>
        <StackPanel>
            <local:CustomTextBox Text="Hello World!" FontSize="30" IsHightLighted="True"></local:CustomTextBox>
        </StackPanel>
    </Window>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25

    附加属性

    在这里插入图片描述

        <StackPanel>
            <!--<local:CustomTextBox Text="Hello World!" FontSize="30" IsHightLighted="True"></local:CustomTextBox>-->
            <local:CustomTextBox Text="Hello World!" FontSize="30">
                <local:CustomTextBox.IsHightLighted>
                    true
                </local:CustomTextBox.IsHightLighted>
                <Grid.Row>1</Grid.Row>
            </local:CustomTextBox>
        </StackPanel>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    
        
    
        
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();
            //TextBoxHelper.SetTitle(aoteman, "this is aoteman");
        }
    }
    
    public class CustomTextBox : TextBox
    {
        public bool IsHightLighted
        {
            get { return (bool)GetValue(IsHightLightedProperty); }
            set { SetValue(IsHightLightedProperty, value); }
        }
    
        public static readonly DependencyProperty IsHightLightedProperty =
            DependencyProperty.Register("IsHightLighted", typeof(bool), typeof(CustomTextBox), new PropertyMetadata(false));
    
        public bool HasText => (bool)GetValue(HasTextProperty);
    
        public static readonly DependencyProperty HasTextProperty;
        public static readonly DependencyPropertyKey HasTextPropertyKey;
    
        static CustomTextBox()
        {
            HasTextPropertyKey = DependencyProperty.RegisterReadOnly(
                "HasText",
                typeof(bool),
                typeof(CustomTextBox),
                new PropertyMetadata(false)
                );
            HasTextProperty = HasTextPropertyKey.DependencyProperty;
        }
    }
    
    public class TextBoxHelper
    {
        public static string GetTitle(DependencyObject obj)
        {
            return (string)obj.GetValue(TitleProperty);
        }
    
        public static void SetTitle(DependencyObject obj, string value)
        {
            obj.SetValue(TitleProperty, value);
        }
    
        // Using a DependencyProperty as the backing store for Title.  This enables animation, styling, binding, etc...
        public static readonly DependencyProperty TitleProperty =
            DependencyProperty.RegisterAttached("Title", typeof(string), typeof(TextBoxHelper), new PropertyMetadata(""));
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53

    TextBox HasText实现一

    
        
        
        
            
            
            
        
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    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.Data;
    using System.Windows.Documents;
    using System.Windows.Input;
    using System.Windows.Media;
    using System.Windows.Media.Imaging;
    using System.Windows.Navigation;
    using System.Windows.Shapes;
    
    namespace Test_01
    {
        /// 
        /// MainWindow.xaml 的交互逻辑
        /// 
        public partial class MainWindow : Window
        {
            public MainWindow()
            {
                InitializeComponent();
            }
        }
    
        public class TextBoxHelper
        {
            public static bool GetHasText(DependencyObject obj)
            {
                return (bool)obj.GetValue(HasTextProperty);
            }
    
            public static void SetHasText(DependencyObject obj, bool value)
            {
                obj.SetValue(HasTextProperty, value);
            }
    
            public static readonly DependencyProperty HasTextProperty =
                DependencyProperty.RegisterAttached(
                    "HasText",
                    typeof(bool),
                    typeof(TextBoxHelper),
                    new PropertyMetadata(false)
                );
    
            public static bool GetMonitorTextChange(DependencyObject obj)
            {
                return (bool)obj.GetValue(MonitorTextChangeProperty);
            }
    
            public static void SetMonitorTextChange(DependencyObject obj, bool value)
            {
                obj.SetValue(MonitorTextChangeProperty, value);
            }
    
            // Using a DependencyProperty as the backing store for MonitorTextChange.  This enables animation, styling, binding, etc...
            public static readonly DependencyProperty MonitorTextChangeProperty =
                DependencyProperty.RegisterAttached(
                    "MonitorTextChange",
                    typeof(bool),
                    typeof(TextBoxHelper),
                    new PropertyMetadata(false, MonitorTextChangedPropertyChanged)
                );
    
            private static void MonitorTextChangedPropertyChanged(
                DependencyObject d,
                DependencyPropertyChangedEventArgs e
            )
            {
                if (d is TextBox box == false)
                {
                    throw new NotSupportedException();
                }
                if ((bool)e.NewValue)
                {
                    box.TextChanged += TextChanged;
                    SetHasText(box, !string.IsNullOrEmpty(box.Text));
                }
                else
                {
                    box.TextChanged -= TextChanged;
                }
            }
    
            private static void TextChanged(object sender, TextChangedEventArgs e)
            {
                var box = sender as TextBox;
                SetHasText(box, !string.IsNullOrEmpty(box.Text));
            }
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87
    • 88
    • 89
    • 90
    • 91
    • 92
    • 93
    • 94

    TextBox HasText只读实现二

    <Window x:Class="Test_01.MainWindow"
            xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
            xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
            xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
            xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
            xmlns:local="clr-namespace:Test_01"
            mc:Ignorable="d" 
            Title="MainWindow" Height="450" Width="800">
        <Window.Resources>
        </Window.Resources>
        <StackPanel>
            <!--<local:CustomTextBox x:Name="aoteman" local:TextBoxHelper.Title="this is test" FontSize="30"
                                 Text="{Binding RelativeSource={RelativeSource self}, Path=(local:TextBoxHelper.Title)}"></local:CustomTextBox>-->
            <TextBox x:Name="tBox" Text="1234" FontSize="30" local:TextBoxHelper.MonitorTextChange="True"></TextBox>
            <CheckBox IsChecked="{Binding ElementName=tBox, Path=(local:TextBoxHelper.HasText), Mode=OneWay}" FontSize="30"></CheckBox>
        </StackPanel>
    </Window>
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Security.Policy;
    using System.Text;
    using System.Threading.Tasks;
    using System.Windows;
    using System.Windows.Controls;
    using System.Windows.Data;
    using System.Windows.Documents;
    using System.Windows.Input;
    using System.Windows.Media;
    using System.Windows.Media.Imaging;
    using System.Windows.Navigation;
    using System.Windows.Shapes;
    
    namespace Test_01
    {
        /// 
        /// MainWindow.xaml 的交互逻辑
        /// 
        public partial class MainWindow : Window
        {
            public MainWindow()
            {
                InitializeComponent();
            }
        }
    
        public class TextBoxHelper
        {
            static TextBoxHelper()
            {
                HasTextProperty = HasTextPropertyKey.DependencyProperty;
            }
    
            public static bool GetHasText(DependencyObject obj)
            {
                return (bool)obj.GetValue(HasTextProperty);
            }
    
            public static void SetHasText(DependencyObject obj, bool value)
            {
                obj.SetValue(HasTextPropertyKey, value);
            }
    
            public static readonly DependencyProperty HasTextProperty;
    
            public static readonly DependencyPropertyKey HasTextPropertyKey =
                DependencyProperty.RegisterAttachedReadOnly(
                    "HasText",
                    typeof(bool),
                    typeof(TextBoxHelper),
                    new PropertyMetadata(false)
                );
    
            public static bool GetMonitorTextChange(DependencyObject obj)
            {
                return (bool)obj.GetValue(MonitorTextChangeProperty);
            }
    
            public static void SetMonitorTextChange(DependencyObject obj, bool value)
            {
                obj.SetValue(MonitorTextChangeProperty, value);
            }
    
            public static readonly DependencyProperty MonitorTextChangeProperty =
                DependencyProperty.RegisterAttached(
                    "MonitorTextChange",
                    typeof(bool),
                    typeof(TextBoxHelper),
                    new PropertyMetadata(false, MonitorTextChangedPropertyChanged)
                );
    
            private static void MonitorTextChangedPropertyChanged(
                DependencyObject d,
                DependencyPropertyChangedEventArgs e
            )
            {
                if (d is TextBox box == false)
                {
                    throw new NotSupportedException();
                }
                if ((bool)e.NewValue)
                {
                    box.TextChanged += TextChanged;
                    SetHasText(box, !string.IsNullOrEmpty(box.Text));
                }
                else
                {
                    box.TextChanged -= TextChanged;
                }
            }
    
            private static void TextChanged(object sender, TextChangedEventArgs e)
            {
                var box = sender as TextBox;
                SetHasText(box, !string.IsNullOrEmpty(box.Text));
            }
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87
    • 88
    • 89
    • 90
    • 91
    • 92
    • 93
    • 94
    • 95
    • 96
    • 97
    • 98
    • 99
    • 100
    • 101

    {Binding}解释

    1. local:TextBoxHelper.MonitorTextChange="True":这是自定义属性local:TextBoxHelper.MonitorTextChange的设置,是自定义控件或附加属性的一部分。这个属性被用来监测文本的变化。
    2. :这是一个复选框控件,其中包含了数据绑定。
      • IsChecked="{Binding ...}":这部分指示IsChecked属性将被绑定到某个数据源。
      • ElementName=tBox:这是一个Binding的设置,指定了数据源是哪个控件,即名为"tBox"的TextBox控件。
      • Path=(local:TextBoxHelper.HasText):这是Binding的路径设置。告诉WPF应用程序查找名为"tBox"的控件,并在该控件上查找名为"HasText"的属性。这个属性用于确定TextBox中是否有文本。

    关于这些概念的详细解释

    • ElementName:这是一个Binding设置,用于指定绑定的数据源控件的名称。在示例中,数据源是名为"tBox"的TextBox。
    • Path:这是用于指定数据源控件上的属性或属性路径的设置。在这里,你正在查找名为"HasText"的属性,该属性被用于确定CheckBox的IsChecked属性。
    • (local:TextBoxHelper.HasText):这种写法通常用于引用附加属性,其中local表示当前命名空间,TextBoxHelper是一个附加属性的名称,而HasText是这个附加属性的属性名。
      这种绑定方式可以用于将一个控件的属性绑定到另一个控件的属性,使它们保持同步,例如,在文本框中输入文本时,相关的复选框的选中状态也会相应地改变。这种绑定通常用于实现界面元素之间的交互和数据同步。

    e.NewValue解释
    e.NewValue 是一个 DependencyPropertyChangedEventArgs 对象的属性,它用于存储关于依赖属性更改的信息。

    1. 含义e.NewValue 表示在依赖属性更改时,属性的新值。当一个依赖属性的值发生变化时,e.NewValue 将包含新值,以便可以在事件处理程序中访问并使用它。
    2. 作用e.NewValue 主要用于在属性更改事件处理程序中获取属性的新值。它允许在属性值发生变化时采取相应的操作。例如,可以根据新值来更新界面元素、执行计算或触发其他操作。
    3. 类型e.NewValue 的类型取决于被监测属性的类型。它是一个 object 类型,因为它需要能够表示任何类型的值。通常,需要将其转换为适当的类型,以便在代码中使用。这个类型转换通常是基于知道将要更改的属性的类型。例如,在上述代码示例中,似乎假定属性的新值是一个布尔值。

    在提供的代码示例中,if ((bool)e.NewValue) 的作用是检查某个依赖属性的新值是否为 true,以决定是否执行特定的操作。这是一个典型的用例,其中 e.NewValue 用于确定如何响应属性的更改。

  • 相关阅读:
    【Go入门】 Go如何使得Web工作
    『现学现忘』Git基础 — 4、Git下载与安装
    PostgreSQL 给表添加自增字段脚本
    Java.lang.Class类 toString()方法有什么功能呢?
    恶意文件分类
    mysql 安装问题 mariadb-libs is obsoleted by mysql-community-libs
    [管理与领导-113]:IT人看清职场中的隐性规则 - 10 - 看清人的行动、行为、手段、方法背后的动机与背景条件
    linux java 环境变量配置
    doxygen制作接口文档
    rust学习特殊的地方——函数返回值
  • 原文地址:https://blog.csdn.net/zzyzxb/article/details/134218931