Showing posts with label Silverlight. Show all posts
Showing posts with label Silverlight. Show all posts

Saturday, April 30, 2011

Several things that I always need in an application

Recently I have started on quite a few applications, and I found that reinventing the wheel has been a big part of the effort in them. They are all Data Binding applications in Silverlight/WPF. Several things that I found always needed in my applications:
1. Deep Clone: Definitely needed if you need a decent Undo/Redo capability in a Data Binding application.
2. Converters: Converters are a godsend in Silverlight/WPF application. If you are using Data Binding, which is the way to do a Silverlight/WPF app, then you have to use them. Out of the many converters that I did, these are my favorites:
a. Boolean To Visibility
b. Boolean To Brush
3. Implements INotifyPropertyChanged: This is also a given in a Data Binding application. One particular thing about my classes are that they may be from a Web Service (generated by SvcUtil) and you need to conform to the way SvcUtil choosen to implement the INotifyPropertyChanged.
4. Extend classes generated by the SvcUtil from Web Services: Mostly for direct use as the View Model. There are many traps and tricks when doing this. One of them is the inability to step through because of the stupid DebuggerStepThroughAttribute SvcUtil put on every class it generates.
5. Collection that is a union/combo of other collections: A view, so to speak, that merges contents from two or more ObservableCollections and show them as one. On top of that, I also need INotifyCollectionChanged events fired correctly on it when sub collections changed.
6. SetterValueBindingHelper: A great tool by Delay (David Anson) that solves the problem in Silverlight 2/3 (Can not set binding in Style setters).

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, August 27, 2010

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.

Monday, August 23, 2010

Fully Qualified Type Name in Silverlight

You can ignore the Culture and PublicKey, and they will be defaulted to "neutral" and "null" respectively. However, you must have the following three components in order for Type.GetType(typename) to return you the correct type (otherwise, you will get a Null/Nothing, which is very frustrating).
1. FullName (Namespace + Class name, etc. Complicated when it is a nested class, or generic class, etc.)
2. Assembly
3. Version
An example is:
"DMS.RuleEditor.ViewModel.Logical, RuleEditorViewModel, Version=1.0.0.0"

Find out position of an UIElement in Silverlight

Use GeneralTransform to get the position of the UI Element:

1 GeneralTransform objGeneralTransform = myObj.TransformToVisual(Application.Current.RootVisual as UIElement);
2 Point point = objGeneralTransform.Transform(new Point(0, 0));
3 double myObjTop = point.Y;
4 double myObjLeft = point.X;