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.
How do I listen to changes in Dependency properties from within an attached dependency property?
You can create a PropertyChangeNotifier
class as described in this blog post
After you create it you can use it on attached properties like this:
ListBox listbox = new ListBox();
...
PropertyChangeNotifier notifier = new PropertyChangeNotifier(listBox, “(Grid).Row”);
notifier.ValueChanged += new EventHandler(OnValueChanged);
Also, DependencyPropertyDescriptor doesn't exists in .net 4.5 client profile. However, it does exist in the normal profile. So if you must have it just change the target framework of your project.
Listen to DependencyProperty changed event and get the old value
Unfortunately, you don't get old value information when registering property changed event handler this way.
One workaround is to store property value somewhere (this is your 'old' value) and then compare it to current value in the event handler.
Another workaround is to create your own dependency property (DP) and create binding between your DP and the control's DP. This will give you change notification in the WPF style.
Here is an article about this.
Property Changed in DependencyProperty
When you add an item to the ChartEntries
collection, you do not actually change that property, so the PropertyChangedCallback isn't called. In order to get notified about changes in the collection, you need to register an additional CollectionChanged
event handler:
private static void OnChartEntriesChanged(
DependencyObject obj, DependencyPropertyChangedEventArgs e)
{
var chartView = (ChartView)obj;
var oldCollection = e.OldValue as INotifyCollectionChanged;
var newCollection = e.NewValue as INotifyCollectionChanged;
if (oldCollection != null)
{
oldCollection.CollectionChanged -= chartView.OnChartEntriesCollectionChanged;
}
if (newCollection != null)
{
newCollection.CollectionChanged += chartView.OnChartEntriesCollectionChanged;
}
}
private void OnChartEntriesCollectionChanged(
object sender, NotifyCollectionChangedEventArgs e)
{
...
}
It would also make sense not to use ObservableCollection<ChartEntry>
for the property type, but simply ICollection
or IEnumerable
instead. This would allow for other implementations of INotifyCollectionChanged
in the concrete collection type. See here and here for more information.
How to subscribe to change DependencyProperty?
Here is one way of doing it, using the handy DependencyPropertyDescriptor class.
var pd = DependencyPropertyDescriptor.FromProperty(TextBox.TextProperty, typeof(TextBox));
pd.AddValueChanged(myTextBox, OnTextChanged);
private void OnTextChanged(object sender, EventArgs e)
{
...
}
How To Raise Property Changed events on a Dependency Property?
Implement
INotifyPropertyChanged
in your class.Specify a callback in the property metadata when you register the dependency property.
In the callback, raise the
PropertyChanged
event.
Adding the callback:
public static DependencyProperty FirstProperty = DependencyProperty.Register(
"First",
typeof(string),
typeof(MyType),
new FrameworkPropertyMetadata(
false,
new PropertyChangedCallback(OnFirstPropertyChanged)));
Raising PropertyChanged
in the callback:
private static void OnFirstPropertyChanged(
DependencyObject sender, DependencyPropertyChangedEventArgs e)
{
PropertyChangedEventHandler h = PropertyChanged;
if (h != null)
{
h(sender, new PropertyChangedEventArgs("Second"));
}
}
Listening to dependency property changes on one viewmodel from another viewmodel
For your class CustomerViewModel
I can see only fields of type string in it, so you can use MemberwiseClone() method to create a clone object for CustomerViewModel.
public class CustomerViewModel
{
.....
public CutomerViewModel Clone()
{
return (CustomerViewModel)MemberwiseClone();
}
.....
}
And in your MainWindowViewModel
when Being Shipped checkBox get checked:
ShippedCustomer = BilledCustomer.Clone();
Dependency Property on a user control not updating the property when bound data changes
The setter has a console trace that never fires so I am confident that the property is never being set.
This is a trap. The property getters and setters you have defined are for your convenience. The WPF Framework will not call them, it will use the dependency property directly. Never do anything in those getters and setters that you need to get done.
If you want to react to property changes, use the callback you already discovered. Your console trace should be in there, not in the setter.
Related Topics
Error - Unable to Access the Iis Metabase
Should Functions Return Null or an Empty Object
Why Use 'Virtual' for Class Properties in Entity Framework Model Definitions
Options for Embedding Chromium Instead of Ie Webbrowser Control with Wpf/C#
How to Handle Dependency Injection in a Wpf/Mvvm Application
How to Get Current User, and How to Use User Class in MVC5
Entity Framework 4 Delete Object from Entity Collection
Nhibernate Aliastobean Transformer Associations
How to Set Properties on Struct Instances Using Reflection
Why Is Cross Thread Operation Exception Not Thrown While Running Exe in Bin\Debug
Deserialize a JSON Array in C#
Console Application Closes Immediately After Opening in Visual Studio
Executing Ssis 2012 Package That Has Script Components from External Application
Must Declare Scalar Variable @Id
Order of Items in Classes: Fields, Properties, Constructors, Methods