2009-07-06 8 views
30

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

que 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 archivos DLL de salida (los proyectos no se encuentran en una sola solución).

estoy definiendo una piel (algunos pinceles y estilos en una ResourceDictionary) en la biblioteca "infraestructura". Me gustaría que la aplicación principal seleccione un aspecto y lo ponga a disposición de toda la aplicación (a través del MergedDictionaries en App.xaml).

En mi módulo Quiero usar 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 "StaticResource reference 'MainBackgroundBrush' no se encontró". Esto efectivamente me impide usar el diseñador.

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

+2

Si bien esto no responde a su pregunta técnicamente en absoluto, Expression Blend 2 no tiene problemas con las operaciones de búsqueda de doble vía indirecta y hace salir acaba de encontrar en estos casos específicos en mi experiencia. – scwagner

+0

En VS2010 Beta 1, puede seguir utilizando el diseñador si no puede encontrar un recurso. Te da una advertencia y luego parece ignorar el atributo. –

Respuesta

3

Una posible solución es utilizar DynamicResource en lugar de StaticResource. El diseñador de Visual Studio 2008 simplemente muestra los controles sin ningún estilo, como lo hace VS2010 beta 1 cuando no puede resolver StaticResource.

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

he encontrado algunas cuestiones relacionadas con el apoyo a esta:

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

4

Usted puede crear su propia clase ResourceDictionary, heredando de ResourceDictionary. Luego puede organizar que en el momento del diseño este ResourceDictionary personalizado cargue algunos estilos definidos explícitamente (es decir, los cargados desde la aplicación en tiempo de ejecución), mientras que en el tiempo de ejecución no hace nada en absoluto. La IsInDesignMode-Property podría evaluarse para esto.

Digamos 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 diseñador funcione. En Runtime, puede hacer que su DesignTimeResourceDictionary omita la carga de recursos y logre el comportamiento deseado.

Si necesita, puede crear realmente una copia de los recursos reales para esto, o puede simplemente crear un diccionario ficticio que contenga todas las claves que necesita para mantener al diseñador trabajando.

0

Solo quiero extender Simon D. answer. Lo que está proponiendo es la solución que estoy usando en este momento. Solo quería compartir el código fuente completo. Es de esta fuente Trick To Use A ResourceDictionary Only When In Design Mode.

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