Disappearing Style Setters in Silverlight 3 and WP7 – fixed in Silverlight 4

I’ve come across a really annoying bug in Silverlight 3 that seems to be fixed in Silverlight 4, but still present in WP7. When creating a Style object in runtime, then setting that as the Style of an element in the visual tree, the Value properties in the Setters of the original Style are set to null!

The problem

I’ve come across this issue because I was trying to clone styles with the following extension method:

public static Style Clone(this Style style)
{
    if (style == null)
        return null;
    Style clonedStyle = new Style(style.TargetType);
    clonedStyle.BasedOn = style.BasedOn;
    foreach (Setter setterToCopy in style.Setters)
    {
        clonedStyle.Setters.Add(new Setter()
        {
            Property = setterToCopy.Property,
            Value = setterToCopy.Value
        });
    }
    return clonedStyle;
}

As you can see, this clone method is not doing anything complicated: it is simply iterating through the Setters of the Style and creating new Setter instances with the Property and Value of the original Setters – basically deep cloning the Style itself.

The issue in Silverlight 3

When I did clone a Style that had been created on the fly and had been assigned a the Style of an element, the values of Setters magically were set to null in Silverlight 3. The problem is visualized using the following simple code:

Style dynamicallyCreatedStyle = new Style(typeof(Rectangle));
dynamicallyCreatedStyle.Setters.Add(new Setter(Rectangle.StrokeThicknessProperty, 4));
dynamicallyCreatedStyle.Setters.Add(new Setter(Rectangle.StrokeProperty, new SolidColorBrush(Colors.Red)));
Rectangle1.Style = dynamicallyCreatedStyle.Clone(); // Works fine
Rectangle2.Style = dynamicallyCreatedStyle; // The Value of all Setters in dynamicallyCreatedStyle are set to null because of a Silverlight 3 bug
Rectangle3.Style = dynamicallyCreatedStyle.Clone(); // The Value of all Setters of dynamicallyCreatedStyle are null, thus Rectangle 3 won't be shown in Silverlight 3!

See the example in Silverlight 3 below. As you can notice, the third rectangle isn’t showing as the Style that it’s assigned to it (the clone of dynamicallyCreatedStyle) has all of it’s Setter Values set to null:

The issue in Windows Phone 7: exception being thrown

In Windows Phone 7 the same code still results in incorrect behaviour with an exception being thrown.

The Value of the Setter is not set to null, instead it’s value can’t be determined runtime, in the debugger. Cloning of this Style is still possible, however when assigning this cloned style to in this line:

Rectangle3.Style = dynamicallyCreatedStyle.Clone()

and ArgumentException is thrown with the error message The parameter is incorrect.

Silverlight 4: issue fixed

When compiling the very same code in Silverlight 4, the Values of the Setters of the dynamically created Style are no longer set to null. Here is the same example targeted for Silverlight 4:

Using Silverlight 4, the third rectangle is showing in the application. Kudos for the Silverlight team for fixing this (as far as I was aware) undocumented issue with Styles.

(Note: you can download the source of the example here: Silverlight 3 Styling Issue.zip)

Conclusion

It’s safe to say that due to this bug present in Silverlight 3 and Windows Phone 7, it’s definitely not recommended cloning Styles after they’ve been assigned to visual elements. If you’re forced to modify existing styles on visual elements, I’d suggest to constantly clone them before they’re applied to a visual element. Of course this is an expensive operation, so it’s definitely worth investigating if there are any other options available to avoid this happening in your application.

One Response to Disappearing Style Setters in Silverlight 3 and WP7 – fixed in Silverlight 4
  1. asp.net, c#,javascript... [...]Greg Does IT » Blog Archive » Disappearing Style ... gajotres.com/post/2011/09/20/Drag-and-drop-file-upload.aspx