Поделиться через


Avalon Property Invalidation

If you are writing custom control. You sometimes need to know if your property change so that you
can do something about it. For example, your control is CustomControl and have Size property.
If the Size property change, you need to Invalidate Measure so that it will go back and call your
MeasureCore() again.

For those who are new to writing control. MeasureCore is one of the method that you can override to add your custom measurement code. Other than MeasureCore, there are ArrangeCore, EnsureVisuals, Render and a whole a list of other overrides. The method will be invoked in this sequence:

OnPropertyInvalidated
EnsureVisuals
MeasureCore
ArrangeCore
Render

Back to Property Invalidation. Recently I found out that there are 2 ways to receive notification when your property change. There are as follow:

1. Do it in OnPropertyInvalidated override“

protected override void OnPropertyInvalidated
(MSAvalon.Windows.DependencyProperty dp,
MSAvalon.Windows.PropertyMetadata metadata)
{
// dp can be null, when invalidate all.
if(dp != null)
if(dp.Name == "Size")
{
// ok - this means my Size property is changed.
// in my case, I want to do MeasureCore again.
// you can do other stuff like InvalidateRender etc..
if(this.oldSize != this.Size)
this.InvalidateMeasure();
}
}

2. Register for propertyInvalidatedCallback when you register your Property:

public static readonly DependencyProperty SizeProperty =
DependencyProperty.RegisterAttached("Size", typeof(int),

typeof(CustomControl),
new FrameworkPropertyMetadata(0, false, SysWindows.MetadataFlags.None,
new PropertyInvalidatedCallback(OnSizeInvalidated), null));

In the event when Size property is changed, your callback method "OnSizeInvalidated" will be invoked.

You can use the FrameworkPropertyMetadata class to control what will this property affect. For example, the following FrameworkPropertyMetadata will tell the subsystem that when this property change, it will affect the measurement and this will ensure MeasureCore to be invoked.

FrameworkPropertyMetadata(null, false, MetadataFlags.AffectsMeasure, null, null)

There are other richer MetadataFlags, that allow you to control other things like when this property change,it will affect my parent's Arrange. This is definitely a class to explore.