A dependency property is not a language-level "attribute", but rather a "feature" provided by WPF. It encapsulates some intrinsic behavior on the basis of CLR property, making declarative XAML more powerful for action manipulation, which is obviously much simpler and more natural than writing behavioral events using programming code.
Characteristics of dependent properties:
(1) The use of efficient sparse storage systems means that, without setting local values, the dependency properties of all objects of the same type will share the default settings, greatly saving memory overhead.
(2) The dependency property has the ability to change Notification, and when the value of the property changes, the linkage behavior can be triggered by the metadata information in advance.
(3) A dependency property can inherit a property value from its parent in the tree.
(4) Dependent properties can obtain the final value from multiple providers based on priority.
1. Dependency property Implementation
The implementation of dependent properties is simple:
(1) The type inherits from DependencyObject, and almost all WPF controls inherit indirectly from the type.
(2) Declare a DependencyProperty using public static, which is the true dependency property (field).
(3) completes the metadata registration of the dependent property in the static construct and gets the object reference.
(4) provides an instantiated wrapper property for a dependent property. Note Use the DependencyObject correlation method as a read/accessor.
public class MyClass : DependencyObject
{
public static readonly DependencyProperty TestProperty;
static MyClass()
{
TestProperty = DependencyProperty.Register("Test", typeof(string), typeof(MyClass),
new PropertyMetadata("Hello, World!", OnTestChanged));
}
private static void OnTestChanged(DependencyObject o, DependencyPropertyChangedEventArgs e)
{
}
public string Test
{
get { return (string)GetValue(TestProperty); }
set { SetValue(TestProperty, value); }
}
}
Tip: You can use "PROPDP + TAB" to quickly generate dependent property codes in VS2008.
2. Notice of Change
When a dependency property value changes, WPF completes certain "association behavior" calls through pre-registered metadata (Metadata) information. This allows us to complete the behavior control in the XAML declaration, such as starting or stopping the animation.
We tried to bind the custom dependency property we created above as a source to the related control.
public partial class Window1 : Window
{
MyClass o;
public Window1()
{
InitializeComponent();
o = new MyClass();
var binding = new Binding("Test") { Source = o, Mode = BindingMode.TwoWay };
this.textBox1.SetBinding(TextBox.TextProperty, binding);
}
private void btnTest_Click(object sender, RoutedEventArgs e)
{
o.Test = DateTime.Now.ToString();
}
}
When the form is initialized, TextBox1.Text automatically binds to the default value of Myclass.testproperty "Hello, world!" (Refer to the MyClass static constructed metadata registration code). Whenever we click a button to modify a dependency property (O.test), TextBox1.Text automatically synchronizes updates, which is how dependent properties behave. Of course, we should also provide a completely XAML-based declarative presentation, not the C # code above.
<Window x:Class="Learn.WPF.Window1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="Window1">
<Grid>
<TextBox x:Name="textBox1" />
<Label x:Name="label1" Content="{Binding ElementName=textBox1, Path=Text}" />
</Grid>
</Window>
Label1. Content is bound to textbox1.text this dependency property, and whenever we modify TextBox1.Text, Label1. Content will remain synchronized, and these actions do not require us to write any code. Obviously, this greatly simplifies the behavior control capabilities of XAML, especially the so-called rich functionality control.
WPF provides a mechanism called "triggers (Trigger)" To work with dependent properties, and we look at the effects with a simple property trigger.
<Window x:Class="Learn.WPF.Window1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="Window1">
<Grid>
<Button x:Name="btnTest">
<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>
When a dependent property button.ismouseover changes (= = True), it causes the trigger to execute, setting the foreground=red. Obviously this is much simpler than our handling of MouseEnter events, and the key is that the UI designer does not need to write code to get the desired effect. In addition to property triggers, WPF provides data triggers and event triggers.