Solucionando falhas de carregamento do WPF Designer

O Windows Presentation Foundation (WPF) Designer for Visual Studio inclui um designer visual sofisticado e extensível que processa XAML.Se seu arquivo XAML não carrega no designer, existem diversas coisas que você pode fazer para tentar entender o que está incorreto.Este tópico descreve algumas dicas e técnicas para ajudá-lo a solucionar falhas de carregamento de WPF Designer.

Observação:

Muitas das técnicas contidas neste tópico também se aplicam a Expression Blend.

Passos para Solucionar Problemas

As seguintes etapas podem ajudar você a solucionar falhas de carregamento de WPF Designer.

  1. Leia qualquer mensagem de exceção que você receber.

    Isso pode parecer óbvio, mas se você receber uma exceção, claramente ler a mensagem.Em alguns casos, pode te ajudar a diagnosticar o problema rapidamente.Para obter mais informações, consulte: Depuração e interpretando erros no criador de WPF.

  2. Determine se o problema está em sua implementação.

    Crie e execute o aplicativo para determinar se o problema é o resultado de sua implementação somente ou uma interação com o WPF Designer.Se o aplicativo cria e executa, o erro em tempo de design provavelmente é causado pela sua implementação.

  3. Use o depurador Visual Studio para passar pelo código em tempo de design.Para obter mais informações, consulte Demonstra Passo a passo: Depuração de controles do WPF personalizados em time de design.

  4. Determine se o problema é um erro ao carregar.

    Se modo Design falha ao carregar por causa de uma exceção, o problema é provavelmente um erro ao carregar.Se você tem um código personalizado que é carregado no tempo de design, e você enfrenta exceções ou carrega falhas em tempo de design, consulte a seção Escrevendo Código para Tempo de Design contida neste tópico.Se você estiver trabalhando com recursos e eles não parecerem estar carregando, consulte a seção UserControl e Recursos de Controles Personalizados em Tempo de Design contida neste tópico.

  5. Revise o código que é carregado no tempo de design.

    Há duas abordagens para escrever código que também executa em tempo de design.A primeira abordagem é escrever um código de defesa, verificando os parâmetros de entrada para as classes.A segunda abordagem é verificar se o modo de design está ativo chamando o método GetIsInDesignMode.Para obter mais informações, consulte a seção Escrevendo Código para Tempo de Design contida neste tópico.

  6. Examine outras áreas do seu código.

    Revise o Dicas de programação seção deste tópico para algumas dicas de programação quando você trabalha com o WPF Designer. Examine a seção Recomendações de Programação deste tópico para obter técnicas sobre como escrever um código mais robusto.

  7. Se você ainda tiver problemas, você pode usar o Fórum de WPF designer no MSDN para se conectar com outros desenvolvedores que usam o WPF Designer. Para relatar problemas potenciais ou forneça sugestões, use o O Visual Studio e .NET estrutura comentários site.

Escrever Código para Tempo de Design

Garanta que seu código seja executado em tempo de design, bem como em tempo de execução.Se o código executa em tempo de design, não presuma que Application.Current é seu aplicativo.Por exemplo, quando você estiver usando Expression Blend, Current é Expression Blend.Em tempo de design, MainWindow não é a janela principal do seu aplicativo.Operações típicas que causam a falha de um controle personalizado em tempo de design incluem o seguinte.

Há duas abordagens para escrever código para tempo de design.A primeira abordagem é escrever um código de defesa, verificando os parâmetros de entrada para classes, como conversores de valor.A segunda abordagem é verificar se o modo de design está ativo chamando o método GetIsInDesignMode.

Verificar parâmetros de entrada para algumas implementações é necessário porque o ambiente de design fornece tipos diferentes para algumas entradas daqueles fornecidos pelo ambiente de tempo de execução.

Seletores de estilo e conversores de valor geralmente requerem uma dessas abordagens para ser executado corretamente em tempo de design.

Conversores de Valor

Suas implementações personalizadas de IValueConverter devem verificar para null e para o tipo esperado no primeiro parâmetro do método Convert.O XAML a seguir mostra uma ligação com Application.Current que falha em tempo de design se o conversor de valor não é implementado corretamente.

<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>

A vinculação lança uma exceção no tempo de design porque Application.Current refere-se ao aplicativo de designer em vez de seu aplicativo.Para evitar a exceção, o conversor de valor deve verificar seus parâmetros de entrada ou verificar pelo modo de design.

O exemplo de código a seguir mostra como verificar parâmetros de entrada em um conversor de valor que retorna true se dois parâmetros de entrada satisfazem lógica de negócio específica.

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;
}

A segunda abordagem para escrever código para tempo de design é verificar se o modo de design está ativo.O exemplo de código a seguir mostra uma verificação de modo de design em vez da verificação de parâmetro mostrada anteriormente.

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;
}

Seletores de Estilo

Seus seletores de estilo personalizados também devem ser implementados para executar no modo de design.O XAML a seguir mostra um seletor de modelo personalizado que usa Application.MainWindow em tempo de execução para determinar qual recurso é retornado como um DataTemplate.Em tempo de design, esse recurso pode não estar disponível; então, a substituição de SelectTemplate retorna null em tempo de design.

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

O código a seguir mostra a implementação do seletor de estilo.

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(Window1))
            // 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;
    }
}

UserControl e Recursos de Controle Personalizado em Tempo de Design

Por padrão, UserControl e recursos de controle personalizado que estão disponíveis no tempo de execução podem não estar disponíveis em tempo de design.Quando você adicionar seu controles personalizados e controles de usuário a um Page ou Window na superfície de design, uma instância do controle será criada.Recursos em App.xaml não estão disponíveis para UserControl e instâncias de controle personalizado carregados em uma página ou janela.

Para disponibilizar os recursos em tempo de design, inclua-os em um dicionário de recursos separado e inclua o dicionário no App.xaml e XAML do seu controle.Altere todas as referências StaticResource para referências DynamicResource.O exemplo de código a seguir mostra como compartilhar um dicionário de recurso para que seus recursos estejam disponíveis no tempo de design.

UserControl1.xaml

<UserControl.Resources>
    <ResourceDictionary>
        <ResourceDictionary.MergedDictionaries>
            <ResourceDictionary Source="Dictionary1.xaml" />
        </ResourceDictionary.MergedDictionaries>
    </ResourceDictionary>
</UserControl.Resources>

App.xaml

<Application.Resources>
    <ResourceDictionary>
        <ResourceDictionary.MergedDictionaries>
            <ResourceDictionary Source="Dictionary1.xaml" />
        </ResourceDictionary.MergedDictionaries>
    </ResourceDictionary>
</Application.Resources>

Sintaxe URI de empacotar

Você não deve usar as referências do recurso relativo do aplicativo.O exemplo de código a seguir mostra a sintaxe baseada em aplicativo, que pode falhar em time de design.

<Image Name="image1" Source="pack://application:,,,/Image1.bmp" />

Essas referências são relativas ao aplicativo em vez da DLL.Usando uma referência de recurso relativo do aplicativo em uma DLL torna a DLL dependente de recursos no aplicativo-pai.Essa abordagem é frágil e não garantida trabalhar ao mesmo time de design.

Em vez de usar as referências do recurso relativo do aplicativo, adicionar recursos a DLL propriamente dito e usar componente-com base em referências de recurso.Para obter mais informações, consulte URIs de Pacotes no Windows Presentation Foundation.

Os exemplos de código a seguir mostram a sintaxe baseada em componentes, que é a abordagem recomendada.

<Image Name="image1" Source="/TestHostApp;component/Image1.bmp" />
<Image Name="image1" Source="pack://application:,,,/TestHostApp;component/Image1

Dicas de Programação

A seguir estão algumas dicas de programação para quando você trabalhar com o WPF Designer.

Recomendações de Programação

A seguir estão algumas das melhores opções de programação sobre como escrever um código mais robusto para WPF Designer.

  • Sempre dispor escopos de edição em instruções using ou blocos try/finally.Se uma exceção é gerada, a alteração é anulada na chamada a Dispose.Para obter mais informações, consulte ModelEditingScope.

  • Use um ModelEditingScope Para mover um controle de um contêiner para outro. Se isso não for feito aumenta uma exceção.

  • Em WPF e em WPF Designer, não defina um valor da propriedade para seu padrão se sua intenção for removê-la.Para valores NaN, como Height, chame o método ClearValue em vez de atribuir NaN.

  • Ao recuperar valores de uma propriedade, use o valor da propriedade calculado.Isso significa que você deve usar a propriedade ComputedValue em vez do método GetCurrentValue de ModelItem.O método GetCurrentValue retorna as ligações e outras expressões se elas foram armazenadas no XAML; portanto, você pode obter exceções de conversão em alguns casos.

Consulte também

Outros recursos

Depuração e interpretando erros no criador de WPF

XAML e código Walkthroughs

Conceitos básicos de extensibilidade

Noções básicas sobre extensibilidade Designer WPF