Callback When Dependency Property Recieves Xaml Change

Callback when dependency property recieves xaml change

You would have to register a PropertyChangedCallback with property metadata.

The reason is that dependency properties set in XAML or by bindings or some other source do not invoke the CLR wrapper (the setter method). The reason is explained in the XAML Loading and Dependency Properties article on MSDN:

For implementation reasons, it is computationally less expensive to
identify a property as a dependency property and access the property
system SetValue method to set it, rather than using the property
wrapper and its setter.

...

Because the current WPF implementation of the XAML processor behavior
for property setting bypasses the wrappers entirely, you should not
put any additional logic into the set definitions of the wrapper for
your custom dependency property. If you put such logic in the set
definition, then the logic will not be executed when the property is
set in XAML rather than in code.

Your code should look like this:

public static readonly DependencyProperty IsClosedProperty =
DependencyProperty.Register(
"IsClosed", typeof(bool), typeof(GroupBox),
new FrameworkPropertyMetadata(false,
FrameworkPropertyMetadataOptions.AffectsRender,
(o, e) => ((GroupBox)o).OnIsClosedChanged()));

public bool IsClosed
{
get { return (bool)GetValue(IsClosedProperty); }
set { SetValue(IsClosedProperty, value); }
}

private void OnIsClosedChanged()
{
_rowDefContent.Height = new GridLength((IsClosed ? 0 : 1), GridUnitType.Star);
}

WPF: Run Code when DependencyProperty Is Changed

Clr property is just a wrapper of DependencyProperty, it's usually be by-passed unless you get/set the property directly in code behind. To handle something when the property is changed, you need to provide a PropertyMetadata containing some property changed callback, something like this:

public static readonly DependencyProperty Text1Property =
DependencyProperty.Register("Text1", typeof(string),
typeof(BasicControl), new PropertyMetadata(text1Changed));
//the text1Changed callback
static void text1Changed(DependencyObject o, DependencyPropertyChangedEventArgs e){
var bc = o as BasicControl;
if(bc != null) bc.OnPropertyChanged("Text2");
}

Set DependencyProperty Value in Changed Callback

Typically, if you find yourself in a situation where your code is executing on the UI thread, but prior to a point where it makes sense, it is always possible to offload your work until some future point by using the UI thread's Dispatcher.

For example, if you have code running on startup, yet you expect that UI elements have been loaded and are ready for interaction, you can use the Dispatcher to execute your UI code later.

To do this, first you have to grab the UI Dispatcher. You can do this via Application.Current.Dispatcher and offload execution of your update via BeginInvoke, passing in the method or lambda you wish to invoke later.

This method has an overload that take a DispatcherPriority enumeration. Use an appropriate priority. Typically, I use a priority of ContextIdle, which executes after almost everything you need has completed.

How to propagate PropertyChanged changes in DependencyProperty

Converters should not do more work than simple conversions, your question sounds like the converter uses a lot of properties of the object to create some combined value. Use a MultiBinding instead which hooks into all the different properties on the object you need, that way the MultiValueConverter on that MultiBinding will fire if any of those properties change.

Further, since you seem to create text you might be able to get away without using any converter at all as the StringFormat might be enough.

Listen to changes of dependency property

If it's a DependencyProperty of a separate class, the easiest way is to bind a value to it, and listen to changes on that value.

If the DP is one you're implementing in your own class, then you can register a PropertyChangedCallback when you create the DependencyProperty. You can use this to listen to changes of the property.

If you're working with a subclass, you can use OverrideMetadata to add your own PropertyChangedCallback to the DP that will get called instead of any original one.



Related Topics



Leave a reply



Submit