Path.Data Dependency Property Initialization From String
In Silverlight 2 Beta 1 I used to build dynamic UI with drawing portions.
For example, I used to draw Path dynamically like in following example:
Path myPath = new Path();
myPath.SetValue(Path.DataProperty, "M 50,50 L 50,100 L 100,100 L 100,50 L 50,50 Z");
myPath.SetValue(Path.NameProperty, "myPath");
myPath.Width = 100;
myPath.Height = 100;
myPath.Fill = new SolidColorBrush(Colors.Black);
LayoutRoot.Children.Add(myPath);
This gave me nice rectangle... Everything was fine, until I start to port my project to Silverlight 2 Beta 2. After fixing all known stuff, I finally executed the application and in the moment I expected to get some nice Path being drawn I've got exception:
What happened? Why? It used to work before... Well, the answer is in changes documentation for Beta 2:
SetValue Only Accepts the Correct Types (No Conversions)
Who Is Affected: Silverilght 2 Beta 1 managed applications using SetValue.
Summary and Fix Required
SetValue will only accept the correct types for the given DependencyProperty. For example, if the dependency property Canvas.LeftProperty is of type System.Double, you must supply an object of type System.Double. Conversions will no longer be done. The following is another example:
Beta 1
[C#]
ellipse.SetValue(Ellipse.StrokeProperty, "Black");
Beta 2
[C#]
ellipse.SetValue(Ellipse.StrokeProperty, new SolidColorBrush(Colors.Black));
In Beta 1, the string "Black" would be converted to a SolidColorBrush of color Black automatically. In Beta 2, you must pass in an object of type SolidColorBrush.
Well... How we can do it now? The first way, is to prepare PathGeometry object (probably best, but defiantly not the simple and short way to do it) and set it as DataProperty:
PathGeometry p = new PathGeometry();
//Initialize PathGeometry here
//.....
//.....
//
myPath.SetValue(Path.DataProperty, p);
Another alternative is to develop some functionality, which will mimic WPF's PathFigureCollectionConverter (which is missing in Silverlight)... Well, it is also no so simple task...
Last alternative is to initialize Path object from string with XamlReader.Load functionality:
string pathXaml = "<Path xmlns=\"http://schemas.microsoft.com/winfx/2006/xaml/presentation\" xmlns:x=\"http://schemas.microsoft.com/winfx/2006/xaml\" Data=\"M 50,50 L 50,100 L 100,100 L 100,50 L 50,50 Z\"/>";
Path path = (Path)System.Windows.Markup.XamlReader.Load(pathXaml);
myPath.SetValue(Path.NameProperty, "myPath");
myPath.Width = 100;
myPath.Height = 100;
myPath.Fill = new SolidColorBrush(Colors.Black);
LayoutRoot.Children.Add(myPath);
And it actually works:
Mission accomplished... Path object being initialized from string with minimum changes...
Enjoy,
Alex