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

这篇具有很好参考价值的文章主要介绍了WPF中依赖属性及附加属性的概念及用法。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

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

依赖属性

WPF中依赖属性及附加属性的概念及用法,WPF,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));
    }
#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
<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>

附加属性

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

    <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>
<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>

    <!--<local:CustomTextBox x:Name="aoteman" FontSize="30"
                         Text="{Binding RelativeSource={RelativeSource self}, Path=(local:TextBoxHelper.Title)}"></local:CustomTextBox>-->
</StackPanel>
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(""));
}

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)}" FontSize="30"></CheckBox>
    </StackPanel>
</Window>
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
{
    /// <summary>
    /// MainWindow.xaml 的交互逻辑
    /// </summary>
    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));
        }
    }
}

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>

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
{
    /// <summary>
    /// MainWindow.xaml 的交互逻辑
    /// </summary>
    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));
        }
    }
}

{Binding}解释

  1. local:TextBoxHelper.MonitorTextChange="True":这是自定义属性local:TextBoxHelper.MonitorTextChange的设置,是自定义控件或附加属性的一部分。这个属性被用来监测文本的变化。
  2. <CheckBox IsChecked="{Binding ElementName=tBox, Path=(local:TextBoxHelper.HasText)}" FontSize="30">:这是一个复选框控件,其中包含了数据绑定。
    • 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 用于确定如何响应属性的更改。文章来源地址https://www.toymoban.com/news/detail-743938.html

到了这里,关于WPF中依赖属性及附加属性的概念及用法的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • WPF XAML中使用依赖属性

    自定义的控件 MyCustomControl ,它有一个依赖属性 MyProperty 。首先,我们需要在控件的代码文件中创建这个依赖属性: 在XAML文件中使用这个控件及其依赖属性: 在这个例子中, local 是XAML文件中定义的XML命名空间前缀, clr-namespace:WpfApp 指定了 MyCustomControl 定义所在的命名空间。

    2024年02月20日
    浏览(43)
  • vuex中mapActions的概念及用法

    先看一下官方文档对mapActions的描述: 简单来说 mapActions 就是 将组件中的函数映射为对应的action 。 一般情况下我们会在组件中使用 this.$store.dispatch() 来触发 action ,想要调用多少个 action 就需要调用多少次 dispatch() ,而使用 mapActions 的话只需要 往 mapActions 中传入与 action 同名

    2024年02月13日
    浏览(39)
  • 【WPF】附加事件

    Microsoft 官方概述:   附加事件可用于在非元素类中定义新的 路由事件 ,并在树中的任何元素上引发该事件。 为此, 必须将附加事件注册为路由事件 ,并提供支持附加事件功能的特定 支持代码 。 由于附加事件注册为路由事件,因此在元素树中引发时,它们会传播到元素

    2024年02月05日
    浏览(74)
  • WPF使用依赖注入

    现在依赖注入在.Net里面已经普及,自己常写一些简单的demo倒是无所谓,但偶尔写一点正式的工程,也免不了要使用一下,于是总结了一下在WPF里面使用依赖注入。 在写简单Demo时候,通常是在MainWindow的构造函数里面直接做初始化,各种变量也都丢在MainWindow类里面。在使用依

    2024年02月11日
    浏览(34)
  • WPF 用户控件依赖注入赋值

    我一直想组件化得去开发WPF,因为我觉得将复杂问题简单化是最好的 cs部分 我将复杂的依赖注入的代码进行了优化,减少了重复内容的输入。 我现在依赖属性扩展封装在一个静态文件里面 记得UserControl.xaml里面绑定你ViewModel。这样的话有代码提示 我后面要根据Vue的单向数据

    2024年02月07日
    浏览(44)
  • 【WPF应用39】WPF 控件深入解析:SaveFileDialog 的属性与使用方法

    在 Windows Presentation Foundation (WPF) 中,SaveFileDialog 控件是一个非常重要的文件对话框,它允许用户在文件系统中选择一个位置以保存文件。这个控件提供了很多属性,可以自定义文件对话框的显示内容和行为。 本文将详细介绍 SaveFileDialog 控件的属性和功能,如何在 WPF 应用程序

    2024年04月12日
    浏览(50)
  • 掌握WPF控件:熟练常用属性(二)

    Calendar 用于日期选择的控件。它提供了一个可视化的界面,可以通过它来选择特定的日期。 常用属性 描述 DisplayMode 用来设置Calendar的显示模式,有三种可选值:默认Month(月)、Year(年)和Decade(十年)。 SelectedDate 用来获取或设置当前选中的日期。 Mode 用来设置Calendar的显

    2024年01月20日
    浏览(92)
  • 掌握WPF控件:熟练常用属性(一)

    Border Border控件是一个装饰控件,用于围绕其他元素绘制边框和背景。它提供了一种简单的方式来为其他控件添加边框和背景样式,而无需自定义控件的绘制逻辑。 常用属性 描述 Background 用于设置背景颜色或图像。 BorderBrush 用于设置边框的边框颜色 CornerRadius 用于设置边框的

    2024年01月21日
    浏览(43)
  • WPF绑定与通知属性到界面

    本文同时为b站WPF课程的笔记,相关示例代码 在上一篇文章C#代码事件里面,我们介绍了利用给控件命名的方式,在后端代码中访问并修改属性。这样子直截了当,但是这样后端代码依赖于前端。如果前端的代码变动较大,后端代码可能要大面积重构。 于是利用绑定的这种方

    2024年01月25日
    浏览(48)
  • 深入理解WPF中的依赖注入和控制反转

    在WPF开发中, 依赖注入(Dependency Injection)和控制反转(Inversion of Control)是程序解耦的关键,在当今软件工程中占有举足轻重的地位,两者之间有着密不可分的联系 。今天就以一个简单的小例子,简述如何在WPF中实现依赖注入和控制反转,仅供学习分享使用,如有不足之处

    2024年02月06日
    浏览(52)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包