Solucionar problemas de los errores de carga de WPF y Silverlight Designer

WPF Designer for Visual Studio incluye un diseñador visual complejo y extensible que representa XAML. Si un archivo XAML no se carga en el diseñador, existen varias formas de intentar comprender la causa del error. En este tema se describen algunas sugerencias y técnicas para ayudarle a solucionar problemas de errores de carga de WPF Designer. Los ejemplos que se incluyen en este tema se centran en WPF, pero la mayoría de los problemas, técnicas y soluciones se aplican a WPF y a Silverlight.

Nota

Muchas de las técnicas de este tema también se aplican a Expression Blend.

Depurar un error de carga

Utilice el depurador de Visual Studio para examinar el código en tiempo de diseño. Puede utilizar una segunda instancia de Visual Studio para depurar los errores de carga. Para obtener más información, vea Cómo: Depurar un error de carga del diseñador.

Pasos para la solución de problemas

Los pasos siguientes pueden ayudarle a solucionar problemas de errores de carga de WPF Designer.

  1. Lea todos los mensajes de excepción que reciba.

    Esto puede parecer obvio, pero si obtiene una excepción, lea el mensaje completamente. En algunos casos, puede ayudarle a diagnosticar el problema rápidamente. Para obtener más información, vea Depurar e interpretar errores en WPF Designer.

  2. Determine si el problema está en su implementación.

    Genere y ejecute su aplicación para determinar si el problema sólo es el resultado de su implementación o de una interacción con WPF Designer. Si la aplicación se genera y se ejecuta, es probable que el error en tiempo de diseño esté causado por su implementación.

  3. Determine si el problema es un error de carga.

    Si la Vista de diseño no se carga debido a una excepción, es probable que el problema sea un error de carga. Si tiene código personalizado que se carga en tiempo de diseño y experimenta excepciones o errores de carga en tiempo de diseño, vea la sección Escribir código para tiempo de diseño de este tema.

  4. Revise el código que se carga en tiempo de diseño.

    Existen dos enfoques para escribir código que también se ejecuta en tiempo de diseño. El primer enfoque es escribir código estable comprobando los parámetros de entrada a las clases. El segundo enfoque es comprobar si el modo de diseño está activo llamando al método GetIsInDesignMode. Para obtener más información, vea la sección Escribir código para tiempo de diseño de este tema.

  5. Revise otras áreas del código.

    Revise la sección Sugerencias de programación de este tema para obtener sugerencias de programación cuando trabaje con WPF Designer. Revise la sección Procedimientos recomendados de programación de este tema para informarse sobre las técnicas para escribir un código más sólido.

  6. Si sigue teniendo problemas, puede utilizar WPF Designer forum on MSDN para conectarse con otros programadores que utilizan WPF Designer. Para informar sobre posibles problemas o para ofrecer sugerencias, use el sitio Visual Studio and .NET Framework Feedback.

Escribir código para tiempo de diseño

Asegúrese de que el código se ejecuta en tiempo de diseño, así como en tiempo de ejecución. Si el código se ejecuta en tiempo de diseño, no asuma que Application.Current es su aplicación. Por ejemplo, cuando use Expression Blend, Current es Expression Blend. En tiempo de diseño, MainWindow no es la ventana principal de su aplicación. Entre las operaciones normales que hacen que un control personalizado produzca errores en tiempo de diseño se incluyen las siguientes.

Existen dos enfoques para escribir código para tiempo de diseño. El primer enfoque es escribir código estable comprobando los parámetros de entrada a las clases, por ejemplo, convertidores de valores. El segundo enfoque es comprobar si el modo de diseño está activo llamando al método GetIsInDesignMode. Para Silverlight, utilice la propiedad IsInDesignTool.

Es necesario comprobar los parámetros de entrada para algunas implementaciones porque el entorno de diseño proporciona diferentes tipos para algunas entradas que los que proporciona el entorno en tiempo de ejecución.

Los selectores de estilo y los convertidores de valores normalmente exigen que se ejecute correctamente uno de estos enfoques en tiempo de diseño.

Convertidores de valores

Las implementaciones personalizadas de IValueConverter deben comprobar si hay un valor null y si aparece el tipo esperado en el primer parámetro del método Convert. En el XAML siguiente se muestra un enlace a Application.Current que produce errores en tiempo de diseño si no se implementa el convertidor de valores correctamente.

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

El enlace produce una excepción en tiempo de diseño porque Application.Current hace referencia a la aplicación del diseñador en lugar de a su aplicación. Para evitar la excepción, el convertidor de valores debe comprobar sus parámetros de entrada o comprobar el modo de diseño.

En el ejemplo de código siguiente se muestra cómo comprobar los parámetros de entrada en un convertidor de valores que devuelve true si dos parámetros de entrada satisfacen una lógica de negocios determinada.

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

El segundo enfoque para escribir código para el tiempo de diseño es comprobar si el modo de diseño está activo. En el ejemplo de código siguiente se muestra una comprobación del modo del diseño en lugar de la comprobación de parámetros que se ha mostrado 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;
}

Selectores de estilo

Los selectores de estilo personalizados también se deben implementar para ejecutarse en modo de diseño. En el XAML siguiente se muestra un selector de plantilla personalizado que utiliza Application.MainWindow en tiempo de ejecución para determinar qué recurso se devuelve como DataTemplate. En tiempo de diseño, este recurso no puede estar disponible, de modo que la invalidación de SelectTemplate devuelve null en tiempo de diseño.

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

En el siguiente código se muestra la implementación del selector 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(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;
    }
}

Sugerencias de programación

A continuación se indican algunas sugerencias de programación para cuando trabaje con WPF Designer.

Procedimientos de programación recomendados

A continuación se indican algunos procedimientos de programación recomendados sobre cómo escribir un código más sólido para WPF Designer.

  • Incluya siempre los ámbitos de edición en instrucciones using o en bloques try/finally. Si se produce una excepción, el cambio se anula en la llamada Dispose. Para obtener más información, vea ModelEditingScope.

  • Utilice un objeto ModelEditingScope para mover un control de un contenedor a otro. En caso contrario, se produce una excepción.

  • En WPF y en WPF Designer, no establezca un valor de la propiedad en su valor predeterminado si su intención es borrarlo. Para los valores NaN, como Height, llame al método ClearValue en lugar de asignar NaN.

  • Cuando recupere valores de una propiedad, utilice el valor calculado de la propiedad. Esto significa que debe usar la propiedad ComputedValue en lugar del método GetCurrentValue de ModelItem. El método GetCurrentValue devolverá enlaces y otras expresiones si están almacenados en el XAML, para que pueda convertir las excepciones en algunos casos.

Vea también

Conceptos

Control de excepciones (Depurar)

Otros recursos

Cómo: Depurar un error de carga del diseñador

Depurar e interpretar errores en WPF Designer

Tutoriales para el uso de XAML y código