Deserializing DependencyObjects

Sorry if this is the wrong forum, but is seems that most of the questions dealing with DependencyObjects are in here.

The Setup:

I have a class, say Person, that contains two properties, LastName and FirstName. The class also implements ISerializable. Prior to WPF/WF, I would have two private instance fields (_lastName and _firstName) that would serve as the backing store for the properties. Furthermore, each property would, on Set, validate the data, possibly setting an error field (IDataErrorInfo), raise a PropertyChanged event (INotifyChanged) and mark the object as dirty. Oher processing may be done as necessary.

When the object is deserialized, the serialization constructor sets the private instance fields, never touching the properties. This has the end result of no validation occurring (it is unnecessary), no notifications being raised on the properties, (no one is listening) and the object is not dirty.

The Change:

If I were to change the property backing stores from private instance fields to DependencyProperty fields (in order to gain the databinding benefits with WPF/WF), it appears that the serialization constructor would now have to call the DependencyProperty.SetValue method. That would (seemingly) result in validation occuring, notifications being raised, and the object being set to dirty. (I also understand thru research that WPF does not call the property wrapper, rather calling the DependencyProperty directly. This keeps me from setting the dirty flag in the property.)

The Question:

Long story short, I want to have a dependency property that has all of the cool stuff (validation events, default values, property changed notification), but I do not want any of that stuff fired when deserializing the object.

I figure I'm missing something pretty basic here, and I was hoping someone could point me in the right direction.

Thanks a lot,

Chris Snyder

[1964 byte] By [ChrisB.Snyder] at [2008-1-4]
# 1

As far as I know, if you use DependencyProperties as the backing store for CLR properties, DependencyProperty.SetValue() is the only way you can set values on them (except from data binding, animation or inheritance), theoretically speaking, you should be enble to get into the SetValue, and too examine how it is implemented using reflector, and come up any kinda hack to bypass any restriction imposed by DependencyProperties, but this is really unusual and probably will break if the future implementation of DependencyProperty system changed.

Sheva

ZhouYong at 2007-10-3 > top of Msdn Tech,Visual Studio Orcas,Windows Presentation Foundation (WPF)...
# 2
Chris --

You shouldn't need to use DependencyProperties for data-bound classes. They really aren't intended to be used as a data store for general application data. (And that means your object would need to derive from DependencyObject rather than just object).

Adding INotifyPropertyChanged should, along with a standard CLR object act the way you want. Have you tried that?

In any case, you can add standard CLR property accessors to a DependencyProperty based object. The only reason standard property accessors are added though is for ease of use through code rather than using the more obtuse and not-as-type-friendly Set/Get Value methods.

In WPF, you shouldn't move your objects to using DPs. The INotifyPropertyChanged event should do the trick. If you're having problems with them not working somewhere, do tell!

WPCoder at 2007-10-3 > top of Msdn Tech,Visual Studio Orcas,Windows Presentation Foundation (WPF)...
# 3

Thanks for the advice. My objects already implement the INotifyPropertyChanged and IDataErrorInfo interfaces and our current databinding scheme works like a champ. However, when I originally started reading the dependency property stuff, I misread the statement and thought that the binding source for WPF had to be a DependencyProperty. However, after more research, I find that the binding source can be a lot of different things, but the binding target needs to be a Dependency Property. In other words, I had it backwards.

That changes the discussion to one of a more academic nature: A DependencyProperty has been defined with a coercion call back and a property changed callack. Would it be possible to disable those, or replace them? It appears that one could use the PropertyMetadata.

Sorry for the stupid (or nonsensical) questions. It always happens when I start learning something new.

And again, thanks for the advice.

Chris Snyder

ChrisB.Snyder at 2007-10-3 > top of Msdn Tech,Visual Studio Orcas,Windows Presentation Foundation (WPF)...
# 4
Yes, I suppose you could overwrite the DP callbacks on existing objects, but when you inherit and reuse a DP on a subclass, you declare your own handlers anyway.

Academically speaking, , why would you want to disable or replace them?

WPCoder at 2007-10-3 > top of Msdn Tech,Visual Studio Orcas,Windows Presentation Foundation (WPF)...
# 5

DP.OverrideMetadata API can be used to specify PropertyChangedCallback/CoerceValueCallback.

PropertyChangedCallback has an additive mergeing behavior with those specified by the base class. This means that both the change callbacks specified by the base class and the sub class are both called when a change occurs. The order is base class then sub class.

CoerceValueCallback on the other hand has replace semantics. If the sub class specifies one, then that replaces the one specified by the base class. In the absence of a CoerceValueCallback for the sub class, the base class callback will be used instead.

And in your earlier scenario you talk about marking an object dirty when a property is set. To do this with DPs you'd need to add a PropertyChangedCallback for the DP and set the dirt bit in there. As you've already discovered the CLR wrapper for a DP is not guaranteed to be called. So it is not recommended to add any special logic in your CLR settor or gettor.

VarshaMahadevan-MSFT at 2007-10-3 > top of Msdn Tech,Visual Studio Orcas,Windows Presentation Foundation (WPF)...

Visual Studio Orcas

Site Classified