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**。当鼠标悬停在按钮上时,它会更改按钮的前景色。当鼠标离开按钮时,它会恢复到原来的颜色。

Dependency Property

为什么我们需要依赖属性

在应用程序中使用依赖属性可以获得各种好处。在以下情况下,可以使用依赖属性代替 CLR 属性:

  • 如果要设置样式
  • 如果要进行数据绑定
  • 如果要使用资源(静态或动态资源)
  • 如果要支持动画

基本上,依赖属性提供了许多使用 CLR 属性无法获得的功能。

下面列出了 **依赖属性** 和其他 **CLR 属性** 的主要区别:

  • CLR 属性可以使用 **getter** 和 **setter** 直接读写类的私有成员。相反,依赖属性不存储在本地对象中。

  • 依赖属性存储在 DependencyObject 类提供的键/值对字典中。它还节省了大量内存,因为它只在属性更改时才存储属性。它也可以在 XAML 中绑定。

自定义依赖属性

在 .NET 框架中,也可以定义自定义依赖属性。请按照以下步骤在 C# 中定义自定义依赖属性。

  • 使用系统调用 register 声明并注册您的 **依赖属性**。

  • 为属性提供 **setter** 和 **getter**。

  • 定义一个 **静态处理程序**,它将全局处理发生的任何更改

  • 定义一个 **实例处理程序**,它将处理对该特定实例发生的任何更改。

下面的 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 { 
   /// <summary> 
      /// Interaction logic for UserControl1.xaml 
   /// </summary> 
	
   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(); 
      }  
   } 
}

这是定义 TextBlock 为用户控件的 XAML 文件,并且 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。

Dependency property for user
广告