Dot-Net

Wpf 合併的資源字典無法從 app.xaml 中辨識

  • June 12, 2013

我有一個 WPF .net 4.5 應用程序,在合併資源字典時遇到問題。

我有與This SO questionThis Question完全相同的問題,但接受的解決方案對我不起作用。

我在 app.xaml 中聲明了一個資源字典,如下所示(為清楚起見進行了簡化):

<Application.Resources>
       <ResourceDictionary.MergedDictionaries>
           <ResourceDictionary Source="Skin/ResourceLibrary.xaml" />              
           <ResourceDictionary Source="Skin/Brushes/ColorStyles.xaml" />               
       </ResourceDictionary.MergedDictionaries>
   </ResourceDictionary>               
</Application.Resources>

問題: 應用程序可以“看到”在 app.xaml 中列出的 ColorStyles 字典,但如果我將其移動/嵌套在 ResourceLibrary.xaml 中,則應用程序不會“看到”ColorStyles.xaml 並且有關缺少靜態資源的錯誤出現。

這是我創建 ResourceLibrary.xaml 字典(簡化)的方法:

<ResourceDictionary 
   xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
   xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">

   <ResourceDictionary.MergedDictionaries>

       <!--  BRUSHES AND COLORS  -->
       <ResourceDictionary Source="Brushes/ColorStyles.xaml" />

   </ResourceDictionary.MergedDictionaries>
</ResourceDictionary>

**更改原因:**我目前的資源字典組織很糟糕,我需要更改它(因為我不止一次創建對象)。我想在“皮膚”文件夾中有一個資源字典,然後是用於組織剩餘樣式字典的子文件夾,這些字典將全部合併到 ResourceLibrary.xaml 文件中,該文件又將在 app.xaml 中呼叫。

我嘗試了什麼: 是的,我確實嘗試使用上面連結中的解決方案:

<Application.Resources>
   <ResourceDictionary>
       <ResourceDictionary.MergedDictionaries>
           <ResourceDictionary Source="Skin/ResourceLibrary.xaml"/>
       </ResourceDictionary.MergedDictionaries>
       <!-- Dummy Style, anything you won't use goes -->
       <Style TargetType="{x:Type Rectangle}" />
   </ResourceDictionary>
</Application.Resources>

但我在虛擬樣式行收到以下錯誤:

錯誤 2 屬性元素不能位於元素內容的中間。它們必須在內容之前或之後。

由於 lisp 註釋,將程式碼更改為以下程式碼消除了上面的錯誤:

<Application.Resources>
   <ResourceDictionary>
       <!--Global View Model Locator-->
       <vm:ViewModelLocator x:Key="Locator" d:IsDataSource="True" />

       <!-- Dummy Style, anything you won't use goes -->
       <Style TargetType="{x:Type Rectangle}" />

       <ResourceDictionary.MergedDictionaries>
           <ResourceDictionary Source="Skin/ResourceLibrary.xaml"></ResourceDictionary>             
           <ResourceDictionary Source="Skin/Brushes/ColorStyles.xaml" />
           <ResourceDictionary Source="Skin/NamedStyles/AlertStyles.xaml" />

       </ResourceDictionary.MergedDictionaries>
   </ResourceDictionary>               
</Application.Resources>

但資源庫仍未被呼叫。

我還嘗試將所有文件路徑更改為打包 URI,但這也沒有解決問題。

我嘗試將 resourceLibrary.xaml 和其他資源字典移動到不同的類庫項目中(使用與上述相同的文件夾結構和文件)。然後我使用了以下 URI,但我仍然無法訪問在 ResourceLibrary.xaml 文件中聲明的資源。

<ResourceDictionary Source="pack://application:,,,/FTC.Style;component/ResourceLibrary.xaml" />

但同樣,如果我將每個資源字典添加到 App.Xaml 文件中,使用上面的 UIR 格式,這些資源是可用的。

錯誤消失了,但我仍然無法使用作為 ResourceLibrary.xaml 文件中合併字典一部分的資源。我傾向於同意 dowhilefor 關於我是否應該使用這種方法的評論,但我想弄清楚這一點,因為這個問題的最常見解決方案(參見本文頂部的連結)不起作用,也許這個解決方案可以幫助別人。

問題: 為什麼 ResourceLibrary.xaml 文件被忽略?

我對 MergedDictionaries 有一個大問題,我相信你的問題是一樣的。我希望我的 ResourceDictionaries 組織得當,這對我來說意味著有單獨的 Buttons.xaml、TextBoxes.xaml、Colors.xaml 等。我將它們合併到 Theme.xaml 中,通常所有樣式都在一個單獨的程序集中(以便我可以輕鬆切換主題)。我的 ApplicationResources 如下:

<Application.Resources>
 <ResourceDictionary>
   <ResourceDictionary.MergedDictionaries>
     <ResourceDictionary Source="/DefaultTheme;component/Theme.xaml" />
   </ResourceDictionary.MergedDictionaries>
   <Style TargetType="{x:Type Ellipse}"/>
 </ResourceDictionary>
</Application.Resources>

並且在主應用程序程序集中定義的 .xamls 中的每個 StaticResource 都可以正常工作,預設樣式都可以使用虛擬樣式。 不起作用的是 Theme 內 .xamls 之間的 StaticResources。如果我在 Buttons.xaml 中定義一個使用 Colors.xaml 中的 StaticResource 的樣式,則會收到有關 StaticResources 和 UnsetValue 的錯誤。如果我將 Colors.xaml 添加到 Application MergedDictionaries,它將起作用。

解決方案 0

放棄組織。將所有內容放在一個 .xaml 中。我相信這就是通常應該使用 ResourceDictionaries 的方式,因為 MergedDictionaries 存在所有“問題”(​​對我來說,這將是一場噩夢)。

解決方案 1

將主題內的所有跨 xaml StaticResource 引用更改為 DynamicResource。它可以工作,但要付出代價,因為 DynamicResources 比 StaticResources 更“重”。

解決方案 2

在使用來自另一個 .xaml 的 StaticResources 的每個主題 .xaml 中,將另一個 ResourceDictionary 添加到 MergedDictionaries。這意味著 Buttons.xaml、TextBoxes.xaml 和其他將在其 MergedDictionaries 中包含 Colors.xaml。這將導致 Colors ResourceDictionary 以多個副本儲存在記憶體中。為避免這種情況,您可能需要查看SharedResourceDictionary

解決方案 3

通過不同的 ResourceDictionaries 設置,不同的嵌套我想出了一個理論

如果在上面的同一 .xaml 或此 ResourceDictionary 的 MergedDictionaries 中未找到 StaticResource,則會在其他頂級 MergedDictionaries中搜尋它。

我寧願只向 ApplicationResources 添加一個 .xaml,但我通常最終使用兩個.xaml 。您不必將 Theme 中的每個 .xaml 添加到 ApplicationResources,只需 - 例如 - Controls.xaml(任何類型的 MergedDictionaries 嵌套,但不允許 Controls.xaml 的字典之間的交叉引用)和 Common.xaml其中包含所有常見的控制項資源。如果 Common.xaml 嵌套也是允許的,但沒有交叉引用,則不能有單獨的 Colors.xaml 和 Brushes.xaml 使用顏色作為靜態資源 - 那麼您必須將 3 個 .xaml 添加到 Application MergedDictionaries。

現在我總是使用第三種解決方案,但我認為它並不完美,仍然想知道是否有更好的方法。我希望我正確地解釋了您所描述的與我相同的問題。

引用自:https://stackoverflow.com/questions/17057934