2009-07-06 16 views
30

Come evitare errori di progettazione di Visual Studio quando una risorsa WPF viene definita in un progetto separato?Evitare errori di progettazione di Visual Studio quando la risorsa WPF è definita nel progetto separato

Ho tre progetti in un'applicazione WPF composita: l'applicazione principale, una libreria "infrastruttura" e una libreria "modulo". L'applicazione principale fa riferimento agli altri progetti tramite le DLL di output (i progetti non si trovano in un'unica soluzione insieme).

Sto definendo una skin (alcuni pennelli e stili in un ResourceDictionary) nella libreria "infrastruttura". Vorrei che l'applicazione principale selezionasse una skin e la rendesse disponibile per l'intera applicazione (tramite MergedDictionaries in App.xaml).

Nel mio modulo voglio utilizzare le risorse definite nella skin caricate dall'applicazione principale. Se faccio riferimento alla risorsa come se fosse localmente disponibile in questo modo:

Background={StaticResource MainBackgroundBrush} 

quasi tutto funziona come desiderato. L'eccezione è che il designer di Visual Studio viene confuso e mi dice che "Riferimento a StaticResource 'MainBackgroundBrush' non è stato trovato". Questo mi impedisce in modo efficace di usare il designer.

Cosa posso fare per definire un "skin" ResourceDictionary in un progetto, fare riferimento a tale skin nell'applicazione principale e quindi utilizzare le sue risorse in un progetto di modulo?

+2

Anche se questo non tecnicamente rispondere alla tua domanda a tutti, Expression Blend 2 non ha problemi con la ricerca a doppia indirezione e rende fuori solo trovare in questi casi specifici nella mia esperienza. – scwagner

+0

In VS2010 Beta 1 è ancora possibile utilizzare il progettista se non riesce a trovare una risorsa. Ti dà un avvertimento e quindi sembra ignorare l'attributo. –

risposta

3

Una possibile soluzione è utilizzare DynamicResource anziché StaticResource. Il designer di Visual Studio 2008 visualizza semplicemente i controlli senza alcuno stile, come fa VS2010 beta 1 quando non è in grado di risolvere uno StaticResource.

L'utilizzo di DynamicResource è appropriato in situazioni in cui uno stile particolare può cambiare in fase di esecuzione, ad esempio quando si scava.

ho trovato alcune domande relative a sostegno di questa:

Ho anche trovato una persona che afferma che DynamicResource dovrebbe essere usato ogni volta che una risorsa non è locale :

4

È possibile creare la propria classe ResourceDictionary, eredita da ResourceDictionary. Quindi è possibile concordare che in fase di progettazione questo ResourceDictionary personalizzato carichi alcuni stili definiti esplicitamente (cioè quelli caricati dall'app in runtime), mentre in fase di esecuzione non fa nulla. La proprietà IsInDesignMode potrebbe essere valutata per questo.

Supponiamo che tu abbia una classe di questo tipo, chiamata "DesignTimeResourceDictionary", quindi usi semplicemente s.th. come

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

per caricare le risorse in fase di progettazione e far funzionare il progettista. In runtime è possibile quindi rendere DesignTimeResourceDictionary saltare il caricamento delle risorse e ottenere il comportamento desiderato.

Se è necessario, è possibile creare una copia delle risorse reali per questo, oppure è sufficiente creare un dizionario fittizio contenente tutte le chiavi necessarie per far funzionare il progettista.

0

Voglio solo estendere la risposta di Simon D. Quello che sta proponendo è la soluzione che sto usando in questo momento. Volevo solo condividere il codice sorgente completo. È da questa fonte 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> 
Problemi correlati