Thursday, January 20, 2011

One thing hard learnt regarding Dependency Properties

I was scratching my head like crazy on this one but could not figure it out. It turns out that: if you put a default value of reference type in the Register function of DependencyProperty, this vaue will be shared by ALL instances of the property and cause problems. For example, if you have a property of the type Collection, then all data added to that collection will "magically" show up in other instances too! This has bothered me for a long time and I finally found a good explaination at this web page.

Friday, September 17, 2010

Another anomaly in Silverlight

I can not get a TextBlock to be HitTest'd. If I change it to TextBox, HitTest works. But not on a TextBlock, not even with IsHitTestVisible to true.

Friday, September 10, 2010

Can not capture mouse in Silverlight ComboBox

I ran through a problem in implementing Drag and Drop in Silverlight. While it works for button, checkbox, textblocks, etc., CaptureMouse always returns false for a ComboBox. Weird...

Friday, August 27, 2010

Converters does not live well with Data Validation

If you throw an exception in a IValueConverter, then it will be propagated to UI, instead of caught by Data Validation code (Set ValidateOnException=True). Basically you have no way around this. So the only other choice is to add data annotations and do the validation there as suggested in this discussion.
// Confine value between 0 and 1

// type conversion error will be thrown as well

[Range(0,1)]
public int IntValue
{
get { return _intvalue; }
set
{
Validator.ValidateProperty(value,
new ValidationContext(this, null, null) { MemberName = "IntValue" });
_intvalue = value;
}
}


There is another article that describes it better, even though the title says "Silverlight 4 vs Flex 4: Data Validation". (I actually clicked this link while researching this problem, but did not read it until I figured out the problem, and that's after a long time. :()

Xaml has a "Shadows" problem

If you declare a property "Shadows" (in VB terms) another property in its superclass, then Xaml loader will throw out an AmbiguousMatchException because it can not decide which one to use in this case, as a reflection operation will return multiple properties. Solution is to make the property Overridable (or virtual in C#) and overrides it.
The frustrating thing is: Despite the straight forward explanation that you have here, the debugging of this problem takes forever. There are two reasons for it:
1) AmbiguousMatchException does not tell you the offending property name and object it is raising against.
2) Microsoft Symbol Server, which supposedly should give you the source code for mscorlib, only turns out names of the method. No source code, and in turn the call parameters, are provided so there is virtually no way to find out what is wrong unless you have the knowledge and patience to go through the disassembly.
What I did ultimately is very much akin to the S&L (Save and Load) in games. I commented some code and see if the exception is raised. If not, I uncomment some. Until I found out the offending piece of code and discovered this little problem. Which is, by the way, not surprising at all. But it sure made my life miserable in the past 12 hours.

Tuesday, August 24, 2010

Copy Constructor, Clone and Polymorphism

This is an artsy name for a blog. But I think it sums up the puzzle I faced when I try to do deep copy. We will need a Copy Constructor and a Clone (or Copy) method that is polymorphed (virtual) to make deep copy work under polymorphism situations.
Imagine that: You need a deep copy mechanism, and you have an class hierarchy to do the copy. When you do copies, you may get a reference to one of the high level classes. But obviously you need to copy the entire object. So you need to have:
1. A copy constructor on every class.
2. A polymorphed Clone (or Copy) method on every class.
The Clone method should call the copy constructor and the copy constructor will in turn call its parent's copy constructor so all properties are deep copied.

Be careful of MemberwiseClone

If you have noticed, there is a protected method, MemberwiseClone, on Object. It is tempting to use it as it provides a quick way to do shallow copy, which is quite useful sometimes. But I fell into a trap yesterday and finally figured out the root during my walk today. :)
The problem comes from a combination of two factors:
1) MemberwiseClone: I am using it as a cheap way to copy Drag and Dropped content.
2) Parent property: One of the property of all Expression objects that I can copy, is the Parent property that points back to the containing object. This is because of the necessacity to quickly, and reliabilty, find out the parent for certain actions. These actions include Insert an Expression before another, and find out what is the Operator of the Logical expression to display a little "And" or "Or" before the sub expressions.
Long stories short: I drag and dropped a Binary expression "(a+b)" with the "b" being an EmptyExpression. Everything is fine, it seems. But when I drop a second Binary that is the same, problem shows. Because I did a MemberwiseClone on the first Binary, the "b" component of the first is pointing back at the "original" Binary, which is conveniently thrown away at this point. Now when the second Binary is dropped into the "b". "b" went back to the Parent, in this case thrown away, to update its property. Because the thrown away Parent is not show on the UI, it seems nothing is changed. Surprise!
But the worse things comes after: When the old Parent is updating, it dutifully put the "b"'s Parent to nothing, as it is useless now. If I drop another Expression into "b" (which is still shown on the screen), its Parent is empty, and crash happens when it tries to ask its parent to replace itself with the dropped Expression.
This is a twisted explaination. Hopefully I have sometime to draw a Visio to showcase the problem.