How does WPF dependency property design save memory consumption?

I read this at the following link: -

http://www.informit.com/articles/article.aspx?p=688529&seqNum=2

However, since GetValue and SetValue internally use efficient sparse storage and because IsDefaultProperty is a static field (not an instance field), the implementation of the dependency property saves the memory of each instance compared to a typical .NET property. If all the properties of the WPF controls were wrappers around instance fields (like most .NET properties), they will consume a significant amount of memory due to all the local data attached to each instance.

But in the end they are stored somewhere, how does it save memory consumption?

+8
wpf dependency-properties
source share
2 answers

See the following link: http://www.bobpowell.net/dependencyproperty.aspx

What is declared by an object as a dependency property is really nothing more than an identifier. This static β€œproperty” is indeed one that associates an object with a specific storage identifier. For example, graphic objects have the Background property, which can be set explicitly or using templates or styles.

As long as the Dependency property uses its default state (which is very common), it will not occupy any additional memory, since the default value will be used. The default value is not saved per instance, it is stored depending on the dependency property and is set by metadata.

Example, note how Brushes.Black set as the default

 public static readonly DependencyProperty ForegroundProperty = DependencyProperty.Register( "Foreground", typeof(Brush), typeof(TextElement), new FrameworkPropertyMetadata(Brushes.Black, ...)); 

Think of it this way: say you have four TextBlocks in Xaml

 <StackPanel> <TextBlock .../> <TextBlock .../> <TextBlock .../> <TextBlock Foreground="Green" .../> </StackPanel> 

The three TextBlocks at the top have Foreground set to black, although you never set it to black. They use their default value. So, for the Foreground property for the three TextBlocks above, you only need one field (since this is a static field).

For the fourth TextBlock , however, you explicitly set the Foreground to Green, so the value is inserted into the dictionary as the local value for the Foreground in this instance and therefore requires additional memory (this will also end at location # 3 in the list below, overriding Setters , Triggers , etc.).

Also see Josh Smith's next post, he read well: Demystifying dependency properties

There is a well-defined set of rules that is used internally by WPF to find out what the real value of DP is. Here is a brief summary of the priority rules used when resolving a DP value (read more about this here ):

  • Coercion of the ownership system
  • Active or Hold behavior animations.
  • Local value
  • TemplatedParent Template
  • Style triggers
  • Template triggers
  • Style setting
  • Theme Style
  • Inheritance
  • Default value from dependency property metadata

Edit: To respond to a comment from Duane

If you explicitly specify a value with the same value as the default value, it will still be stored as a local value. This is easy to verify with the following Xaml.

Both TextBlocks will have Foreground set to black, but a local value will be set later. Style will only be able to set Foreground in the first TextBlock , and not later, since style installers have a lower priority than the local value.

 <StackPanel> <StackPanel.Resources> <Style TargetType="TextBlock"> <Setter Property="Foreground" Value="Green"/> </Style> </StackPanel.Resources> <TextBlock Text="Displays in Green"/> <TextBlock Foreground="Black" Text="Displays in Black"/> </StackPanel> 
+17
source share

First, suppose you create a class with a dozen properties. Create 100,000 of them. How many object references do you have now? 1,200,000.

Now we implement a class called DependencyObject :

 public class DependencyObject { public DependencyObject() { LocalValues = new Dictionary<string, object>(); } protected Dictionary<string, object> LocalValues { get; set; } public DependencyObject Parent { get; set; } protected object GetValue(string propertyName) { if (LocalValues.ContainsKey(propertyName)) { return LocalValues[propertyName]; } return Parent.GetValue(propertyName); } protected void SetValue(string propertyName, object value) { LocalValues[propertyName] = value; } } 

Create a derived class as follows:

 public class MyDependencyObject : DependencyObject { public SomeType Property1 { get { return (SomeType)GetValue("Property1"); } set { SetValue("Property1", value]; } } // create 11 more properties like this } 

Now create 100,000 instances of MyDependencyObject and set them to Parent . How many object references are used (not counting the parent)? 300,000.

How property inheritance works in dependency objects.

+5
source share

All Articles