How do internal / dependent properties work and where are the values โ€‹โ€‹stored?

I'm a little obscure with all this magic. Since I realized that dependency properties are inherited from DependencyObject, so the values โ€‹โ€‹are saved:

  • in the instance itself, if a value is assigned (in the local dictionary)
  • or taken from a link to the parent if the value is not specified.

    protected object GetValue(string propertyName) { if (LocalValues.ContainsKey(propertyName)) { return LocalValues[propertyName]; } return Parent.GetValue(propertyName); } 

    Am I right about that?

I also don't understand where the values โ€‹โ€‹for attached properties are stored?

 Control.FontSizeProperty = TextElement.FontSizeProperty.AddOwner( typeof(Control), new FrameworkPropertyMetadata(SystemFonts.MessageFontSize, FrameworkPropertyMetadataOptions.Inherits)); 

Does the AddOwner method call the Attached property assign a value to the instance field? When does this happen and where does the meaning go?

Thanks!

+6
source share
2 answers

The property system in WPF is quite complex. MSDN does contain a lot of information, but it is often difficult to find. Although there are many ways DependencyProperty can be installed , I'm not sure if you need to take care of where the values โ€‹โ€‹are stored.

For local values, you can assume that they are stored in a DependencyObject (again you care about where it is stored), with the caveat that they are not stored on a row basis. This is really related to the DependencyProperty instance. This is why you would like to add an owner to the property. If someone sets TextElement.FontSize to your control, this is exactly the same as setting the local FontSize property.

As for the inheritance of values โ€‹โ€‹for a property from the parent, this only happens with attached properties. From the MSDN entry for FrameworkPropertyMetadataOptions :

Although inheritance of properties may seem to be properties of unbound dependencies, the inheritance behavior for an unbound property through certain element boundaries at run time is undefined. Always use RegisterAttached to register properties where you specify Inheritance in metadata.

+3
source

Dependency property values โ€‹โ€‹are stored inside objects (derived from DependencyObject) to which we apply the property value.

Take your attached TextElement.FontSizeProperty property, for example:

 <StackPanel TextElement.FontSize="20" ... > ... </StackPanel> 

XAML parser translates it to the following:

 ... TextElement.SetFontSize(stackPanel, 20); ... 

which internally:

 public static void SetFontSize(DependencyObject element, double value) { element.SetValue(TextElement.FontSizeProperty, value); } 

So setting TextElement.FontSize on the stackPanel is the same as calling

 stackPanel.SetValue(TextElement.FontSizeProperty, value) 

SetValue () is a method defined in the DependencyObject class. Many complex things happen inside the method, but in the end, the effective value of the dependency property is wrapped in a structure called EffectiveValueEntry and stored in the following instance field inside DependencyObject:

 private EffectiveValueEntry[] _effectiveValues; 
+3
source

Source: https://habr.com/ru/post/951564/


All Articles