2009-02-23 9 views
10

Ich habe eine Windows Forms-Anwendung, die zur Laufzeit ein WPF-Steuerelement hosten muss. Ich habe das grundlegende Hosting und die Interaktion abgeschlossen (mit einem ElementHost-Steuerelement) und alles funktioniert gut, bis ich versuche, etwas zu tun, das das WPF-Steuerelement benötigt, um einige benutzerdefinierte Ressourcenwörterbücher zu verwenden, die definiert sind. (Die WPF-Steuerelement und alle seine Ressourcen Wörterbücher alle in der gleichen WPF Control Library DLL definiert sind.)Laden/Verwenden von Ressourcenwörterbüchern aus einem von WinForms gehosteten WPF-Steuerelement

Sobald das passiert, ich ein paar Fehler erhalten, die wie folgt aussehen:

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

Ich habe eine gefunden (Link scheint wegen der Archivierung, thiskönnte derselbe Artikel sein, der ursprünglich referenziert wurde). das spricht zwar darüber, aber es sieht so aus, als ob der Artikel sich mehr der WPF-Seite nähert, aber ich möchte nicht wirklich Änderungen an der WPF-Steuerung vornehmen müssen, da alles in einer eigenständigen WPF-Anwendung läuft.

Wenn der einzige Weg dies zu tun ist, Änderungen auf der WPF-Seite vorzunehmen, kann ich diese Änderungen vornehmen (ich bin nicht verantwortlich für die WPF-Steuerbibliothek, aber die Person, die auch für die gleiche Firma arbeitet, so ist es kein Problem, außer dass ich seine Zeit habe, die Änderungen vorzunehmen.) Aber ich hoffe auf etwas, was ich auf der WinForms-Seite tun kann, damit das funktioniert.

Die WPF-Control-Bibliothek hat ein Dateiressourcenverzeichnis namens „Default.xaml“ definierte im Projekt mit den folgenden Eigenschaften:

Build Action: Seite kopiert Ausgabeverzeichnis: Kopieren Sie nicht Custom Tool: MSBuild Kompilieren

die Stand-alone-WPF-Anwendung hat der folgende Eintrag in seiner App.xaml Datei:

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

es ist wie die Steuer Bibliothek scheint sollte schon wissen, wie t o seine Ressourcen bekommen. Die Verwendung von Resources.MergedDictionaries.Add() scheint zu funktionieren, aber wo bekomme ich die Instanz des vorhandenen Wörterbuchs?

Antwort

4

Vorausgesetzt, Sie wissen, welche Ressourcen Sie benötigen (klingt wie Sie), sollten Sie sie einfach selbst "injizieren" können. So etwas wie:

In Ihrer Frage erwähnen Sie, dass es vorhandene Ressourcenwörterbücher in der Kontrollbibliothek gibt. Wenn ja, können Sie dies nur tun:

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

Wo würde der „Schlüssel“ und „Wert“ kommen aus für den Anruf hinzufügen? –

+0

Das macht mehr Sinn, aber sollten die Wörterbücher nicht schon zusammengeführt werden? Ich habe meine Frage mit einigen weiteren Informationen zur WPF-Seite aktualisiert. –

+0

Sie sind gerockt, es hat magisch funktioniert. Du hast wirklich meine Zeit gerettet. –

1

Für Ressourcen Wörterbücher Ladens, die in die Assembly eingebettet sind, habe ich die folgenden Schnipsel verwenden für sie während der Laufzeit geladen:

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

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

Dies würde auch zum Laden eines Wörterbuchs im ausführbaren Verzeichnis.

0

Angenommen, Sie haben Ihre Stile/Vorlagen/Ressourcen in viele Dateien Resources1.xaml und Resources2.xaml unterteilt, können Sie sie in einem einzigen Ressourcenwörterbuch (AllResources.xaml) aggregieren. Ein Ressourcenwörterbuch kann einfach zu einem Steuerelement in der XAML-Datei des Steuerelements hinzugefügt werden. Siehe das Beispiel unten.

(!) Set Resources1.xaml, Resources2.xaml und AllResources.xaml Aktionen 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 als

hinzufügen Ressourcen Wörterbücher Quellen bauen relativ Pfade zum 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> 

schließlich in Ihrem Usercontrol

<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>