visual tutorial studio que español ejemplos wpf visual-studio-2008 xaml skinning pack-uri

tutorial - wpf visual studio



Evitar los errores del diseñador de Visual Studio cuando se define el recurso WPF en un proyecto separado (3)

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

Tengo tres proyectos en una aplicación compuesta de WPF: la aplicación principal, una biblioteca de "infraestructura" y una biblioteca de "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 máscara (algunos pinceles y estilos en un ResourceDictionary ) en la biblioteca de "infraestructura". Me gustaría que la aplicación principal seleccione un MergedDictionaries y lo ponga a disposición de toda la aplicación (a través de MergedDictionaries en App.xaml).

En mi módulo, quiero usar los recursos definidos en el skin que carga la aplicación principal. Si hago referencia al recurso como si estuviera disponible localmente de esta manera:

Background={StaticResource MainBackgroundBrush}

casi todo funciona como se desee. 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 ResourceDictionary "skin" en un proyecto, hacer referencia a ese skin en la aplicación principal y luego usar sus recursos en un proyecto de módulo?


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

Digamos que tiene una clase de este tipo, llamada ''DesignTimeResourceDictionary'', entonces simplemente usa s.th. me gusta

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

cargar sus recursos en tiempo de diseño y hacer que el diseñador trabaje. En Runtime puede hacer que su DesignTimeResourceDictionary salte la carga de recursos y logre el comportamiento deseado.

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


Solo quiero extender la respuesta de Simon D. Lo que está proponiendo es la solución que estoy usando en este momento. Solo quería compartir el código fuente completo. Es a partir de este truco para utilizar una fuente ResourceDictionary solo cuando en 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>


Una posible solución es usar DynamicResource 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 un StaticResource .

El uso de DynamicResource es apropiado en situaciones en las que un estilo en particular puede cambiar en el tiempo de ejecución, como cuando se despelleja.

Encontré algunas preguntas relacionadas que respaldan esto:

También encontré a alguien que afirma que DynamicResource debe usarse siempre que un recurso no sea local: