2009-07-06 12 views
30

如何在獨立項目中定義WPF資源時避免Visual Studio設計器錯誤?在單獨項目中定義WPF資源時避免Visual Studio設計器錯誤

我在一個複合WPF應用程序中有三個項目:主應用程序,「基礎結構」庫和「模塊」庫。主應用程序通過它們的輸出DLL引用其他項目(項目不在同一個解決方案中)。

我在「infrastructure」庫中定義了一個皮膚(ResourceDictionary中的一些畫筆和樣式)。我希望主應用程序選擇一個皮膚並將其提供給整個應用程序(通過App.xaml中的MergedDictionaries)。

在我的模塊中,我想使用主應用程序加載的外觀中定義的資源。如果我引用的資源,就好像它是本地可用這樣的:根據需要

Background={StaticResource MainBackgroundBrush} 

幾乎所有的功能。例外是Visual Studio的設計人員感到困惑,並告訴我「找不到StaticResource參考'MainBackgroundBrush'」。這有效地阻止了我使用設計師。

我能做些什麼來定義「皮膚」 ResourceDictionary在一個項目中,引用的是皮膚的主要應用程序,然後利用其資源在模塊項目?

+2

雖然這在技術上並不能解決您的問題,但Expression Blend 2在雙重間接查找方面沒有問題,並在我的經驗中找到了這些特定情況。 – scwagner 2009-07-07 04:58:55

回答

3

一個可能的解決方案是使用DynamicResource而不是StaticResource。 Visual Studio 2008設計人員只是簡單地顯示控件而沒有任何樣式,就像VS2010 beta 1在無法解析StaticResource時所做的那樣。

使用DynamicResource適用於某些特定樣式可能在運行時更改的情況,例如在蒙皮時。

我發現了一些相關的問題,支持這一點:

我還發現有人誰規定DynamicResource時應使用的資源不在本地:

4

你可以創建自己的ResourceDictionary類,從的ResourceDictionary繼承。 然後,您可以在設計時安排此自定義ResourceDictionary加載一些明確定義的樣式(即在運行時從應用程序加載的樣式),而在運行時則不會執行任何操作。 可以爲此評估IsInDesignMode-屬性。

假設你有這樣一個類,名爲'DesignTimeResourceDictionary',那麼你只需要使用s.th.像

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

在設計時加載你的資源,使設計人員的工作。 在運行時,您可以使您的DesignTimeResourceDictionary跳過資源加載並實現所需的行爲。

如果您需要,您可以真正爲此創建實際資源的副本,或者您可以創建一個虛擬字典,其中包含保持設計人員工作所需的所有密鑰。

0

我只是想擴展Simon D.答案。他提出的是我現在使用的解決方案。我只是想分享完整的源代碼。這是從這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> 
相關問題