WPF - 依赖属性

  • 简述

    在 WPF 应用程序中,依赖属性是扩展 CLR 属性的特定类型的属性。它利用了 WPF 属性系统中可用的特定功能。
    定义依赖属性的类必须继承自 DependencyObject 类。 XAML 中使用的许多 UI 控件类都派生自 DependencyObject 类,它们支持依赖属性,例如Button 类支持 IsMouseOver 依赖属性。
    以下 XAML 代码创建一个带有一些属性的按钮。
    
    <Window x:Class = "WPFDependencyProperty.MainWindow" 
       xmlns = "http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
       xmlns:x = "http://schemas.microsoft.com/winfx/2006/xaml" 
       xmlns:local = "clr-namespace:WPFDependencyProperty"
       Title = "MainWindow" Height = "350" Width = "604"> 
         
       <Grid> 
          <Button  Height = "40" Width = "175" Margin = "10" Content = "Dependency Property"> 
             <Button.Style> 
                <Style TargetType = "{x:Type Button}"> 
                   <Style.Triggers> 
                             
                      <Trigger Property = "IsMouseOver" Value = "True"> 
                         <Setter Property = "Foreground" Value = "Red" /> 
                      </Trigger>
                                  
                   </Style.Triggers>
                </Style> 
             </Button.Style> 
          </Button> 
       </Grid> 
         
    </Window> 
    
    XAML 中的 x:Type 标记扩展具有与 C# 中的 typeof() 类似的功能。它用于指定采用对象类型的属性时,例如 <Style TargetType = "{x:Type Button}">
    当上面的代码编译执行后,你会得到下面的MainWindow。当鼠标悬停在按钮上时,它会改变按钮的前景色。当鼠标离开按钮时,它会变回原来的颜色。
    依赖属性
  • 为什么我们需要依赖属性

    当您在应用程序中使用依赖属性时,它会给您带来各种好处。在以下情况下,依赖属性可以在 CLR 属性上使用 -
    • 如果要设置样式
    • 如果你想要数据绑定
    • 如果要设置资源(静态或动态资源)
    • 如果你想支持动画
    基本上,依赖属性提供了许多使用 CLR 属性无法获得的功能。
    依赖属性和其他CLR属性的主要区别如下-
    • CLR 属性可以通过使用gettersetter 直接从类的私有成员中读取/写入。相反,依赖属性不存储在本地对象中。
    • 依赖属性存储在 DependencyObject 类提供的键/值对字典中。它还节省了大量内存,因为它在更改时存储了属性。也可以绑定在 XAML 中。
  • 自定义依赖属性

    在.NET 框架中,也可以定义自定义依赖属性。按照下面给出的步骤在 C# 中定义自定义依赖属性。
    • 使用系统调用寄存器声明并注册您的依赖属性
    • 为属性提供 settergetter
    • 定义一个静态处理程序,它将处理全局发生的任何更改
    • 定义一个实例处理程序,它将处理该特定实例发生的任何更改。
    下面的C#代码定义了一个依赖属性来设置用户控件的SetText属性。
    
    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 WpfApplication3 { 
       /// 
    /// Interaction logic for UserControl1.xaml ///
      
         
       public partial class UserControl1 : UserControl { 
         
          public UserControl1() { 
             InitializeComponent(); 
          }
              
          public static readonly DependencyProperty SetTextProperty = 
             DependencyProperty.Register("SetText", typeof(string), typeof(UserControl1), new 
                PropertyMetadata("", new PropertyChangedCallback(OnSetTextChanged))); 
                        
          public string SetText { 
             get { return (string)GetValue(SetTextProperty); } 
             set { SetValue(SetTextProperty, value); } 
          } 
              
          private static void OnSetTextChanged(DependencyObject d,
             DependencyPropertyChangedEventArgs e) { 
             UserControl1 UserControl1Control = d as UserControl1; 
             UserControl1Control.OnSetTextChanged(e); 
          } 
              
          private void OnSetTextChanged(DependencyPropertyChangedEventArgs e) { 
             tbTest.Text = e.NewValue.ToString(); 
          }  
       } 
    }
    
    这是一个 XAML 文件,其中 TextBlock 被定义为用户控件,Text 属性将由 SetText 依赖属性分配给它。
    以下 XAML 代码创建一个用户控件并初始化其 SetText 依赖属性。
    
    <Window x:Class = "WpfApplication3.MainWindow" 
       xmlns = "http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
       xmlns:x = "http://schemas.microsoft.com/winfx/2006/xaml" 
       xmlns:views = "clr-namespace:WpfApplication3"
       Title = "MainWindow" Height = "350" Width = "604"> 
         
       <Grid> 
          <views:UserControl1 SetText = "Hellow World"/> 
       </Grid> 
         
    </Window> 
    
    让我们运行这个应用程序。您可以立即观察到,在我们的 MainWindow 中,用户控件的依赖属性已成功用作 Text。
    用户的依赖属性