2009-02-23 95 views
10

我有一個Windows窗體應用程序,需要在運行時託管一個WPF控件。我有基本的託管和交互完成(使用ElementHost控件),一切正常,直到我嘗試做一些事情,需要WPF控件使用定義的一些自定義資源字典。 (WPF控件和它的所有資源字典都在同一個WPF控件庫DLL的所有定義。)從WinForms託管的WPF控件加載/使用資源字典

一旦出現這種情況,我收到了一堆錯誤,看起來像這樣:

System.Windows.ResourceDictionary Warning: 9 : Resource not found; ResourceKey='DocumentHeaderInterestStyle' 

我發現有一個reference鏈接因歸檔而死亡,this可能與最初引用的文章相同)。談論此事,但似乎文章正在接近WPF方面的事情,但我並不想對WPF控件進行更改,因爲所有工作都在獨立的WPF應用程序中。

如果要實現這一目標的唯一方法是對WPF進行更改,則可以進行這些更改(我對WPF控件庫不負責,但對同一公司也適用的人員也是如此除了讓自己的時間做出改變之外,這不是一個問題。)但是我希望能夠在WinForms方面做些事情來實現這個目標。

WPF控件庫有一個名爲「Default.xaml」項目具有以下屬性定義的資源字典文件:

生成操作:頁 複製到輸出目錄:不復制 自定義工具:的MSBuild :編譯

的獨立的WPF應用程序中有以下條目的App.xaml文件:

<ResourceDictionary x:Uid="ResourceDictionary_1"> 
     <ResourceDictionary.MergedDictionaries> 
      <ResourceDictionary x:Uid="ResourceDictionary_2" Source="/SmartClient.Infrastructure;component/Themes\Default.xaml"/> 
     </ResourceDictionary.MergedDictionaries> 
    </ResourceDictionary> 

好像控件庫應該已經知道如何牛逼獲得它的資源。使用Resources.MergedDictionaries.Add()似乎應該起作用,但我在哪裏獲得現有字典的實例?

回答

4

假設你知道你需要什麼資源(聽起來像你一樣),你應該能夠自己「注入」它們。例如:

var wpfControl = new ...; 
wpfControl.Resources.Add(...); 
elementHost.Child = wpfControl; 

在您的問題中,您提到控制庫中存在現有的資源字典。如果是這樣,你可以這樣做:

var wpfControl = new ...; 
wpfControl.Resources.MergedDictionaries.Add(/* instance of existing dictionary */); 
elementHost.Child = wpfControl; 
+2

如果將「關鍵」和「價值」來自呼叫添加? – 2009-02-23 21:46:43

1

對於被嵌入到程序集加載資源字典,我用下面的代碼片段在運行時加載它們:

//using System.Windows 
ResourceDictionary dict = new ResourceDictionary(); 
dict.Source = new Uri("MyResourceDictionary.xaml", UriKind.Relative); 

Application.Current.Resources.MergedDictionaries.Add(dict); 

這也可用於在可執行文件目錄中加載字典。

0

假設您將自己的樣式/模板/資源分爲多個文件Resources1.xamlResources2.xaml,您可以將它們彙總到單個資源字典中(AllResources.xaml)。資源字典可以很容易地添加到控件的xaml文件中的控件中。看下面的例子。

(!)套裝Resources1.xamlResources2.xamlAllResources.xaml建設行動Page

Resources1.xaml

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

    <ControlTemplate x:Key="ScrollViewerControlTemplate" TargetType="{x:Type ScrollViewer}"> 
     ... 
    </ControlTemplate> 

    <LinearGradientBrush x:Key="VerticalScrollBarBackground" EndPoint="1,0" StartPoint="0,0"> 
     ... 
    </LinearGradientBrush> 

    <Style x:Key="StyleA" TargetType="{x:Type ScrollBar}"> 
     ... 
    </Style> 

</ResourceDictionary> 

Resources2.xaml

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


    <Style x:Key="StyleB" TargetType="{x:Type ScrollBar}"> 
     ... 
    </Style> 

    <Style x:Key="StyleC" TargetType="{x:Type TextBlock}"> 
     ... 
    </Style> 

</ResourceDictionary> 

AllResources.xaml

添加資源字典來源條相對路徑到AllResources.xaml

<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"> 
    <ResourceDictionary.MergedDictionaries> 
     <ResourceDictionary Source="Resources1.xaml" /> 
     <ResourceDictionary Source="Resources2.xaml" /> 
    </ResourceDictionary.MergedDictionaries> 
</ResourceDictionary> 

最後,在你的用戶控件

<UserControl.Resources> 
    <ResourceDictionary> 
     <ResourceDictionary.MergedDictionaries> 
      <ResourceDictionary Source="pack://application:,,,/projectName;component/PathToTheFileRelativeToProjectRootDirectory/AllResources.xaml 
     <converters:StringToUpperCaseConverter x:Key="StringToUpperCaseConverter" /> 
     <converters:LocalizationEntryToStringCaseConverter x:Key="LocalizationEntryToStringCaseConverter" /> 
    </ResourceDictionary> 
</UserControl.Resources>