Partilhar via


Solucionando problemas de falhas de carga de WPF e Silverlight Designer

O WPF Designer for Visual Studio inclui um sofisticado e extensível visual designer que processa 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. Os exemplos neste tópico se concentram no WPF, mas a maioria de questões, técnicas e soluções aplicar para WPF e Silverlight.

ObservaçãoObservação

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

Uma falha de carregamento de depuração.

Use the Visual Studio debugger to step into your code at design time. Você pode usar uma segunda instância do Visual Studio para depurar carregar falhas. For more information, see Como: Depurar uma falha de carregamento do Designer.

Troubleshooting Steps

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

  1. Read any exception messages you receive.

    Isso pode parecer óbvio, mas se você receber uma exceção, claramente, leia a mensagem. In some cases, it can help you quickly diagnose the problem. For more information see Depuração e interpretando erros no criador de WPF.

  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.

    Revisão do Dicas de programação seção deste tópico para obter algumas dicas de programação quando você trabalha com o WPF Designer. Revisão do Programação melhor Practicess seção deste tópico para obter técnicas sobre como escrever um código mais robusto .

  6. Se você ainda tiver problemas, você pode usar o o FórumWPF Designer no MSDN para conectar com outros desenvolvedores que estejam usando o 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. Para o Silverlight, use o IsInDesignTool propriedade.

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 um ModelEditingScope para mover um controle de um contêiner para outro. Falha ao fazer isso gera uma exceção.

  • In WPF and the WPF Designer, do not set a property value to its default if your intent is to clear it. Para NaN valores, como Height, chame o ClearValueométodo em vez de atribuir 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.

Consulte também

Conceitos

Tratamento de Exceção (Depuração)

Outros recursos

Como: Depurar uma falha de carregamento do Designer

Depuração e interpretando erros no criador de WPF

XAML e código Walkthroughs