2009-07-06 12 views
30

Jak można uniknąć błędów projektanta Visual Studio, gdy zasób WPF jest zdefiniowany w oddzielnym projekcie?Unikanie błędów projektanta Visual Studio, gdy zasób WPF jest zdefiniowany w oddzielnym projekcie

Mam trzy projekty w złożonej aplikacji WPF: główna aplikacja, biblioteka "infrastruktury" i biblioteka "modułowa". Główna aplikacja odwołuje się do innych projektów poprzez ich wyjściowe biblioteki DLL (projekty nie są połączone razem w jednym rozwiązaniu).

Definiuję skórkę (niektóre pędzle i style w ResourceDictionary) w bibliotece "infrastruktury". Chciałbym, aby główna aplikacja wybrała skórkę i udostępniła ją całej aplikacji (poprzez MergedDictionaries w App.xaml).

W moim module chcę użyć zasobów zdefiniowanych w skórze, którą ładuje główna aplikacja. Jeśli odwołuję się do zasobu tak, jakby był dostępny lokalnie w ten sposób:

Background={StaticResource MainBackgroundBrush} 

prawie wszystko działa zgodnie z oczekiwaniami. Wyjątkiem jest to, że projektant Visual Studio jest zdezorientowany i mówi mi, że "StaticResource reference" MainBackgroundBrush "nie został znaleziony". To skutecznie uniemożliwia mi korzystanie z projektanta.

Co mogę zrobić, aby zdefiniować "skórkę" ResourceDictionary w projekcie, wskazać tę skórkę w głównej aplikacji, a następnie użyć jej zasobów w projekcie modułu?

+2

Chociaż to nie jest technicznie odpowiedź na twoje pytanie, Expression Blend 2 nie ma problemów z podwójnym wyszukiwaniem kierunkowym i renderuje się tylko znaleźć w tych konkretnych przypadkach w moim doświadczeniu. – scwagner

+0

W VS2010 Beta 1 nadal można używać projektanta, jeśli nie może on znaleźć zasobu. Daje ostrzeżenie, a następnie wydaje się ignorować atrybut. –

Odpowiedz

3

Jednym z możliwych rozwiązań jest użycie DynamicResource zamiast StaticResource. Projektant Visual Studio 2008 po prostu wyświetla kontrolki bez żadnej stylizacji, tak jak w przypadku wersji beta 1 programu VS2010, gdy nie można rozwiązać problemu z StaticResource.

Stosowanie jest odpowiednie w sytuacjach, w których określony styl może się zmieniać w czasie wykonywania, np. Podczas skórek.

znalazłem kilka podobnych pytań wspierając w ten sposób:

Ja również znaleźć kogoś, kto stwierdza, że ​​DynamicResource powinien być stosowany, gdy zasób nie jest lokalny :

4

Można utworzyć własną klasę ResourceDictionary, dziedziczenie z ResourceDictionary. Następnie można ustawić, że w czasie projektowania ten niestandardowy plik ResourceDictionary ładuje niektóre wyraźnie zdefiniowane style (tj. Te ładowane z aplikacji w czasie wykonywania), podczas gdy w środowisku wykonawczym nie robi nic. Właściwość IsInDesignMode-Property może zostać poddana ewaluacji.

Powiedz, że masz taką klasę, o nazwie "DesignTimeResourceDictionary", a następnie po prostu użyj s.th. jak

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

załadować swoje zasoby w czasie projektowania i sprawić, że projektant będzie działał. W środowisku wykonawczym możesz wtedy uczynić swój DesignTimeResourceDictionary pominięcie ładowania zasobów i osiągnąć pożądane zachowanie.

Jeśli potrzebujesz, możesz naprawdę stworzyć kopię prawdziwych zasobów do tego, lub możesz po prostu stworzyć fikcyjny słownik zawierający wszystkie klucze potrzebne do utrzymania pracy projektanta.

0

Po prostu chcę rozszerzyć odpowiedź Simona D. To, co proponuje, to rozwiązanie, którego teraz używam. Chciałem tylko udostępnić pełny kod źródłowy. Pochodzi z tego źródła 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> 
Powiązane problemy