Friday, September 28, 2007
« Rebutting some questions about CSLA .NET... | Main | Using CSLA .NET 3.0 ebook available (and... »

It is a reasonably well-known fact that WPF misuses the Equals() method in the data binding implementation.

If you set a DataContext to an object, then set it to another object that is logically equal to the first, but which has different data, WFP gladly ignores the new object's data:

form.DataContext = A;
B = A.Clone();
B.Value = "new value";
form.DataContext = B;

Assuming A and B retain logical equality even though Value has changed, this code results in the UI not showing the new value. Apparently the reasoning is that if the objects are equal, then there's no need to update any data through data binding.

Of course this totally confuses ReferenceEquals() with Equals(), and the result is that objects used by WFP can no longer have logical equality. They can only have reference equality.

(or, arguably, WPF forces 100% property-level equality across objects, so equality can extend to two different instances as long as they have absolutely no different property values - which seems entirely useless)

In .NET 3.0 I had a solution, at least in CslaDataProvider. The solution was to temporarily set the DataContext to null, then to the new object. The result was that the faulty (imo anyway) equality comparison was defeated.

Unfortunately, it appears that .NET 3.5 may have "fixed a bug" that prevents this from working. The result is that it appears there is NO WAY TO REFRESH DATA when fields of an object change, but the object's logical identity remains the same.

I'm not yet sure of a final solution. The current situation is very bad, because you can either use WPF or you can have logical equality between objects - but not both.

It might be the case that people who need logical equality will have to implement their own parallel Equals() concept - ignoring the standard one built into .NET. That's a really poor solution, but if Microsoft isn't going to use their own framework responsibly then we're kind of stuck. Of course operators become an issue then, since operator overloading is related to Equals() as well. I suppose you could break that relationship, but then you'd get really odd stuff like this:

x = y is true

x.Equals(y) is false

But if WPF forces Equals() to be ReferenceEquals() instead of actual equality, then we come back to being stuck.

I love WPF - it is really cool. But this particular issue is a real problem. Apparently one without a real solution.

Comments are closed.