Share via


Troubleshooting WPF and Silverlight Designer Load Failures

The WPF Designer for Visual Studio includes a sophisticated and extensible visual designer that renders XAML. If your XAML file does not load in the designer, there are several things that you can do to try to understand what is going wrong. This topic describes some tips and techniques to help you troubleshoot WPF Designer load failures. The examples in this topic focus on WPF, but most of the issues, techniques, and solutions apply to WPF and Silverlight.

Note

Many of the techniques in this topic also apply to Expression Blend.

Debugging a Load Failure

Use the Visual Studio debugger to step into your code at design time. You can use a second instance of Visual Studio to debug load failures. For more information, see How to: Debug a Designer Load Failure.

Troubleshooting Steps

The following steps can help you troubleshoot WPF Designer load failures.

  1. Read any exception messages you receive.

    This may seem obvious, but if you get an exception, clearly read the message. In some cases, it can help you quickly diagnose the problem. For more information see Debugging and Interpreting Errors in the WPF Designer.

  2. Determine if the problem is in your implementation.

    Build and run your application to determine whether the problem is the result of your implementation only, or an interaction with the WPF Designer. If the application builds and runs, the design-time error is likely caused by your implementation.

  3. Determine if the problem is a loading error.

    If Design view fails to load because of an exception, the problem is likely a loading error. If you have custom code that is loaded at design time, and you experience exceptions or load failures at design time, see the Writing Code for Design Time section in this topic.

  4. Review your code that is loaded at design time.

    There are two approaches to writing code that also runs at design time. The first approach is to write defensive code by checking the input parameters to classes. The second approach is to check whether design mode is active by calling the GetIsInDesignMode method. For more information, see the Writing Code for Design Time section in this topic.

  5. Review other areas of your code.

    Review the Programming Tips section of this topic for some programming tips when you work with the WPF Designer. Review the Programming Best Practicess section of this topic for techniques on how to write more robust code.

  6. If you still have problems, you can use the WPF Designer forum on MSDN to connect with other developers who are using the WPF Designer. To report potential issues or provide suggestions, use the Visual Studio and .NET Framework Feedback site.

Writing Code for Design Time

Ensure that your code runs at design time, as well as run time. If your code runs at design time, do not assume that Application.Current is your application. For example, when you are using Expression Blend, Current is Expression Blend. At design time, MainWindow is not your application's main window. Typical operations that cause a custom control to fail at design time include the following.

There are two approaches to writing code for design time. The first approach is to write defensive code by checking the input parameters to classes, such as value converters. The second approach is to check whether design mode is active by calling the GetIsInDesignMode method. For Silverlight, use the IsInDesignTool property.

Checking input parameters for some implementations is necessary because the design environment provides different types for some inputs than those provided by the runtime environment.

Style selectors and value converters usually require one of these approaches to run correctly at design time.

Value Converters

Your custom IValueConverter implementations should check for null and for the expected type in the first parameter of the Convert method. The following XAML shows a binding to Application.Current that fails at design time if the value converter is not implemented correctly.

<ComboBox.IsEnabled>
    <MultiBinding Converter="{StaticResource specialFeaturesConverter}">
        <Binding Path="CurrentUser.Rating" Source="{x:Static Application.Current}"/>
        <Binding Path="CurrentUser.MemberSince" Source="{x:Static Application.Current}"/>
    </MultiBinding>
</ComboBox.IsEnabled>

The binding raises an exception at design time because Application.Current refers to the designer application instead of your application. To prevent the exception, the value converter must check its input parameters or check for design mode.

The following code example shows how to check input parameters in a value converter that returns true if two input parameters satisfy particular business logic.

public object Convert(object[] values, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
    // Check the values array for correct parameters.
    // Designers may send null or unexpected values.
    if (values == null || values.Length < 2) return false;
    if (!(values[0] is int)) return false;
    if (!(values[1] is DateTime)) return false;

    int rating = (int)values[0];
    DateTime date = (DateTime)values[1];

    // If the user has a good rating (10+) and has been a member for 
    // more than a year, special features are available.
    if((rating >= 10) && 
        (date.Date < (DateTime.Now.Date - new TimeSpan(365, 0, 0, 0))))
    {
        return true;
    }
    return false;
}

The second approach to writing code for design time is to check whether design mode is active. The following code example shows a design-mode check instead of the parameter check shown previously.

public object Convert(object[] values, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
    // Check for design mode. 
    if ((bool)(DesignerProperties.IsInDesignModeProperty.GetMetadata(typeof(DependencyObject)).DefaultValue)) 
    {
        return false;
    }

    int rating = (int)values[0];
    DateTime date = (DateTime)values[1];

    // If the user has a good rating (10+) and has been a member for 
    // more than a year, special features are available.
    if((rating >= 10) && 
        (date.Date < (DateTime.Now.Date - new TimeSpan(365, 0, 0, 0))))
    {
        return true;
    }
    return false;
}

Style Selectors

Your custom style selectors also must be implemented to run in design mode. The following XAML shows a custom template selector that uses Application.MainWindow at run time to determine which resource is returned as a DataTemplate. At design time, this resource may not be available, so the SelectTemplate override returns null at design time.

<local:TaskListDataTemplateSelector x:Key="myDataTemplateSelector"/>
<ListBox Width="400" Margin="10"
    ItemsSource="{Binding Source={StaticResource myTodoList}}"
    ItemTemplateSelector="{StaticResource myDataTemplateSelector}"
    HorizontalContentAlignment="Stretch" 
    IsSynchronizedWithCurrentItem="True"/>

The following code shows the implementation of the style selector.

public class TaskListDataTemplateSelector : DataTemplateSelector
{
    public override DataTemplate SelectTemplate(
        object item, 
        DependencyObject container)
    {
        if (item != null && item is Task)
        {
            Task taskitem = item as Task;
            Window window = Application.Current.MainWindow;

            // To run in design mode, either test for the correct window class
            // or test for design mode.
            if (window.GetType() == typeof(MainWindow))
            // Or check for design mode: 
            //if (!DesignerProperties.GetIsInDesignMode(window))
            {
                if (taskitem.Priority == 1)
                return window.FindResource("importantTaskTemplate") as DataTemplate;
                else
                return window.FindResource("myTaskTemplate") as DataTemplate;
            }
        }
        return null;
    }
}

Programming Tips

The following are some programming tips when you work with the WPF Designer.

Programming Best Practices

The following are some programming best practices on how to write more robust code for the WPF Designer.

  • Always wrap editing scopes in using statements or try/finally blocks. If an exception is raised, the change is aborted in the Dispose call. For more information, see ModelEditingScope.

  • Use a ModelEditingScope to move a control from one container to another. Failure to do this raises an exception.

  • In WPF and the WPF Designer, do not set a property value to its default if your intent is to clear it. For NaN values, such as Height, call the ClearValue method instead of assigning NaN.

  • When retrieving values from a property, use the computed value of the property. This means you should use the ComputedValue property instead of the GetCurrentValue method of ModelItem. The GetCurrentValue method returns bindings and other expressions if they were stored in the XAML, so you can get cast exceptions in some cases.

See Also

Tasks

How to: Debug a Designer Load Failure

Concepts

Exception Handling (Debugging)

Other Resources

Debugging and Interpreting Errors in the WPF Designer

XAML and Code Walkthroughs