Cómo evitar errores de diseño de Visual Studio cuando los recursos WPF se define en el proyecto separado

StackOverflow https://stackoverflow.com/questions/1088762

Pregunta

¿Cómo puedo evitar errores de diseño de Visual Studio WPF cuando un recurso se define en el proyecto separado?

Tengo tres proyectos en una aplicación WPF compuesta: la aplicación principal, una biblioteca "infraestructura", y una biblioteca "módulo". La aplicación principal hace referencia a los otros proyectos a través de sus DLL de salida (los proyectos no se encuentran en una única solución juntos).

Estoy definiendo una piel (algunos pinceles y estilos en una ResourceDictionary) en la biblioteca "infraestructura". Me gustaría que la aplicación principal para seleccionar una piel y ponerlo a disposición de toda la aplicación (a través de MergedDictionaries en App.xaml).

En mi módulo Quiero utilizar los recursos definidos en la piel que la principal carga la aplicación. Si hago referencia al recurso como si fuera localmente disponibles como esto:

Background={StaticResource MainBackgroundBrush}

casi todo funciona como se desea. La excepción es que el diseñador de Visual Studio se confunde y me dice que " 'MainBackgroundBrush' referencia StaticResource no se encontró". Esto me impide de manera efectiva el uso del diseñador.

¿Qué puedo hacer para definir un ResourceDictionary "piel" en un proyecto, la referencia que la piel en la aplicación principal, y luego usar sus recursos en un proyecto de módulo?

¿Fue útil?

Solución 2

Una posible solución es usar DynamicResource en lugar de StaticResource. El Visual Studio 2008 diseñador simplemente muestra los controles sin labrar, como VS2010 beta 1 no cuando no puede resolver un StaticResource.

Uso DynamicResource es apropiada en situaciones en las que un estilo particular puede cambiar en tiempo de ejecución, como cuando desollar.

He encontrado algunas preguntas relacionadas que apoyan esta:

También me encontré a alguien que afirma que DynamicResource debe utilizarse siempre que un recurso no es local:

Otros consejos

Se puede crear su propia clase ResourceDictionary, heredando de ResourceDictionary. A continuación, puede disponer que en tiempo de diseño esta costumbre ResourceDictionary cargas estilos alguna explícitamente definidos (es decir, las que se cargan desde la aplicación en tiempo de ejecución), mientras que en tiempo de ejecución no hace nada en absoluto. El IsInDesignMode-propiedad podría ser evaluado para esto.

Supongamos que tiene una clase de este tipo, llamado 'DesignTimeResourceDictionary', entonces sólo tiene que utilizar s.th. como

 <UserControl.Resources>
    <ResourceDictionary>
        <ResourceDictionary.MergedDictionaries>
            <Util:DesignTimeResourceDictionary Source="SomeUriToYourResources"/>
        </ResourceDictionary.MergedDictionaries>
    </ResourceDictionary>
 </UserControl.Resources>

para cargar sus recursos en tiempo de diseño y hacer que el trabajo del diseñador. En tiempo de ejecución a continuación, puede hacer que su DesignTimeResourceDictionary omitir la carga de recursos y lograr el comportamiento deseado.

Si usted necesita, usted podría realmente crear una copia de los recursos reales para esto, o simplemente puede crear un diccionario ficticio que contiene todas las claves que necesita para mantener el diseñador que trabaja.

Sólo quiero extender Simon D. respuesta. Lo que se propone es la solución que estoy usando en este momento. Sólo quería compartir el código fuente completo. Es a partir de esta truco para utilizar un ResourceDictionary Sólo cuando la fuente es el modo de diseño .

public class DesignTimeResourceDictionary : ResourceDictionary
{
    /// <summary>
    /// Local field storing info about designtime source.
    /// </summary>
    private string designTimeSource;

    /// <summary>
    /// Gets or sets the design time source.
    /// </summary>
    /// <value>
    /// The design time source.
    /// </value>
    public string DesignTimeSource
    {
        get
        {
            return this.designTimeSource;
        }

        set
        {
            this.designTimeSource = value;
            if ((bool)DesignerProperties.IsInDesignModeProperty.GetMetadata(typeof(DependencyObject)).DefaultValue)
            {
                base.Source = new Uri(designTimeSource);
            }
        }
    }

    /// <summary>
    /// Gets or sets the uniform resource identifier (URI) to load resources from.
    /// </summary>
    /// <returns>The source location of an external resource dictionary. </returns>
    public new Uri Source
    {
        get
        {
            throw new Exception("Use DesignTimeSource instead Source!");
        }

        set
        {
            throw new Exception("Use DesignTimeSource instead Source!");
        }
    }
}

<Window x:Class="WpfApplication1.MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation Jump "
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml Jump "
    Title="MainWindow" Height="350" Width="525"
    xmlns:local="clr-namespace:WpfApplication1">

  <Window.Resources>
    <local:DesignTimeResourceDictionary DesignTimeSource="pack://application:,,,/BlueColors.xaml"/>
  </Window.Resources>

    <Grid>
      <Button Background="{DynamicResource defaultBackground}"
      HorizontalAlignment="Center" VerticalAlignment="Center">click me</Button>
    </Grid>
</Window>
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top