依赖属性和附加属性

1、依赖属性

依赖属性就是一种可以自己没有值,并能通过使用Binding 从数据源获得值(依赖在别人身上)的属性。

注:propdp ,双击 Tab 键即可。

在WPF 系统中,依赖对象的概念被 DependencyObject类所实现,依赖属性的概念则由DependencyProperty类所实现。DependencyObject具有GetValue和 SetValue两个方法。

自定义IsHighlighted依赖属性,如下:

public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();
            ////公开属性
            //CustomTextBox customTextBox = new CustomTextBox();
            //customTextBox.IsHightLighted = true;
            ////或直接使用SetValue
            //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>

 

2、附加属性

附加属性允许为派生自 DependencyObject 的任何 XAML 元素设置额外的属性/值对,即使该元素未在其对象模型中定义这些额外的属性。 

注:propa ,双击 Tab 键即可。

自定义HsText和MonitorTextChange附加属性,使CheckBox是否勾选与TextBox值是否为空相关联,如下:

<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">
    <StackPanel>
        <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>
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)
        );
    
    //属性值改变时,+-TextChanged事件
    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));
    }
}

 

posted @ 2024-04-18 11:04  茜茜87  阅读(2)  评论(0编辑  收藏  举报