Nick's .NET Travels

Continually looking for the yellow brick road so I can catch me a wizard....

Framework Exceptions in Windows Phone

One of the switches that I often enable in Visual Studio is for it to notify my whenever an exception is thrown. This includes exceptions that are thrown internally by the .NET Framework. To enable this option, launch the Exceptions window from the Debug menu.

image

Select the Common Language Runtime Exceptions and check the Thrown checkbox. Click OK to apply this change

image

Now when you run your application you will see any exceptions that are raised, even if they are handles by you or the .NET Framework. Unfortunately sometimes this can be a bit of a drag because the .NET Framework does quite often throw exceptions, sometimes for legitimate reasons, sometimes not so. One such case is for both the CheckBox and RadioButton (actually the ToggleButton which is the base control is the source of this issue). After enabling Exceptions, add the following xaml to a new project.

<Grid x:Name="ContentPanel" Grid.Row="1" Margin="12,0,12,0">
    <CheckBox Content="Checkbox 1" />
</Grid>

Run your application and you will see the following, completely meaningless, exception being raised.

image

If you look at the call stack, apparently something is calling ToString on the ToggleButton control (ie the base control for the CheckBox you just added).

image

If you examine the ToString code, you’ll see something similar to the following, and you can see the reference to Resx.GetString. From the callstack this seems to be the issue.

public override string ToString()
{
    string text = base.ToString();
    string text2 = (base.Content ?? "").ToString();
    bool? isChecked = this.IsChecked;
    return string.Format(CultureInfo.InvariantCulture, Resx.GetString("ToggleButton_ToString_FormatString"), new object[]
    {
        text,
        text2,
        isChecked.HasValue ? isChecked.Value.ToString() : "null"
    });
}

Following this even further you eventually get to the internal Resx constructor where you can see that it attempts to load an assembly (see second line of the above callstack). This is the line that is failing, because the System.Windows.debug.resources assembly doesn’t exist for us developers Sad smile

internal Resx()
{
    Assembly assembly = base.GetType().Assembly;
    this.resources = new ResourceManager("System.Windows", assembly);
    string assemblyString = "System.Windows.debug.resources, Version=2.0.5.0, Culture=en-US, PublicKeyToken=7cec85d7bea7798e";
    try
    {
       Assembly assembly2 = Assembly.Load(assemblyString);
        this.debugResources = new ResourceManager("System.Windows.debug", assembly2);
    }
    catch (FileNotFoundException)
    {
    }
    this.fallbackResources = new ResourceManager("mscorlib", typeof(object).Assembly);
}

 

The work around for this is relatively simple. Create your own Checkbox class that inherits from CheckBox and override the ToString method.

public class MyCheckBox:CheckBox
{
    public override string ToString()
    {
        return string.Empty;
    }
}

Add this to your layout in place of the CheckBox

<Grid x:Name="ContentPanel" Grid.Row="1" Margin="12,0,12,0">
    <PhoneApp23:MyCheckBox Content="Checkbox 1" />
</Grid>

Run: Look, no Exceptions!

NOTE: Whilst the fact that the exception is thrown in the first place probably isn’t great coding, it has little, if any, effect on your app running in production. I’ve described this work around purely to get around the annoyance of the FileNotFoundException being picked up (the other way would be to specifically exclude this type of exception in the Exceptions dialog). Some ad-hoc testing indicates that this exception has an insignificant effect on performance or rendering times.

Comments are closed