XAML: proprietà di dipendenza

Una proprietà di dipendenza è un tipo specifico di proprietà in cui il valore è seguito da un sistema di proprietà appassionato che fa anche parte dell'app Windows Runtime. Una classe che definisce una proprietà di dipendenza deve essere ereditata dalla classe DependencyObject.

Molte delle classi di controllo dell'interfaccia utente usate in XAML derivano dalla classe DependencyObject e supportano le proprietà di dipendenza. Il codice XAML seguente crea un pulsante con alcune proprietà.

<Window x:Class = "XAMLDependencyProperty.MainWindow"
   xmlns = "http://schemas.microsoft.com/winfx/2006/xaml/presentation"
   xmlns:x = "http://schemas.microsoft.com/winfx/2006/xaml"
   xmlns:local = "clr-namespace:XAMLDependencyProperty"
   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>

L'estensione di markup x: Type in XAML ha una funzionalità simile come typeof () in C #. Viene utilizzato quando vengono specificati attributi che accettano il tipo di oggetto come <Style TargetType = "{x: Type Button}">

Quando compili ed esegui il codice precedente, verrà prodotto il seguente MainWindow. Quando il mouse è sopra il pulsante, cambierà il colore di primo piano del pulsante. Quando il mouse lascia il pulsante, tornerà al suo colore originale.

La principale differenza tra le proprietà di dipendenza e altre proprietà CLR sono:

  • CLR properties can directly read/write from the private member of a class by using getter and setter. In case of dependency properties, it is not stored in a local object.

  • Dependency properties are stored in a dictionary of key/value pairs which is provided by the DependencyObject class.

  • It also saves a lot of memory because it stores the property when changed.

  • It can be bound in XAML as well.

In .NET framework, custom dependency properties can also be defined. Here are the steps to define custom dependency property in C#.

  • Declare and register your dependency property with system call register.

  • Provide the setter and getter for the property.

  • Define a static handler to handle any changes that occur globally.

  • Define an instance handler to handle any changes that occur to that particular instance.

Given below is the code in C# for dependency property which defined to set the SetText property of the user control.

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();
      }
   }
}

Here is the XAML file in which the TextBlock is defined as a user control and the Text property will be assigned to it by the SetText dependency property.

The following XAML code creates a user control with initializing its SetText dependency property and some other properties.

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

Let's run this application and you can see immediately in our MainWindow that dependency property for user control has been successfully used as a Text.