Frage

Ich bin ein WPF-Usercontrol in einem WinForms Container-Hosting. Nun, ich möchte, dass die Usercontrol Thema / Haut in der Lage sein. Dazu habe ich mehrere Ressourcenworte bekommt, das die Definition „Skin“. Wenn meine app startet ich eine „neue System.Windows.Application ()“ erstellen, so dass Application.Current existiert. Um das Thema zu ändern, die alte Haut wird entfernt und eine neue Haut wird in die Anwendungsebene Ressourcenverzeichnis zur Laufzeit zusammengefasst. Allerdings bedeutet dies nicht die dyanamically in dem Usercontrol referenzierten Ressourcen ändern. Ich habe versucht, dies in einer geraden WPF-Anwendung und es funktionierte gut. Ich bin etwas fehlt, oder ist es nicht möglich, dies überhaupt zu tun? By the way, wenn ich eine Haut in die Anwendungsressourcen hinzufügen, bevor die Usercontrol initialisiert wird es funktionieren wird, aber ich kann nicht die Haut nach der den ändern.

Um dies in der einfachsten Art und Weise Repo:

Erstellen Sie eine neue WinForms-Anwendung. Fügen Sie einen WPF-Usercontrol auf die App. Das ist einfach:

<UserControl ...>
   <Grid>
      <Button
         Background="{DynamicResource ButtonBG}"/>
   </Grid>
</UserControl>

Erstellen Sie zwei ResourceDictionaries, White.xaml und Black.xaml (oder was auch immer), die eine SolidColorBrush mit dem Schlüssel ButtonBG mit entsprechender Farbe. In Form1.cs, fügen Sie zwei Tasten und ein Element. Legen Sie das Kind des Elements auf eine Instanz des Benutzersteuerelementes wir gerade erstellt hat. Verdrahten die Tasten, um Ereignisse, die die Haut tauschen:

private void White_Click(object sender, EventArgs e)
{
   Application.Current.Resources.MergedDictionaries[0] = 
      (ResourceDictionary)Application.LoadComponent(
         new Uri(@"\WpfThemes;component\White.xaml", UriKind.Relative)));
}

private void Black_Click(object sender, EventArgs e)
{
   Application.Current.Resources.MergedDictionaries[0] = 
      (ResourceDictionary)Application.LoadComponent(
         new Uri(@"\WpfThemes;component\Black.xaml", UriKind.Relative)));
}

In Program.cs, sicherzustellen, dass Application.Current vorhanden und stellen Sie die anfängliche Haut:

[STAThread]
static void Main()
{
   new System.Windows.Application();

   Application.Current.Resources.MergedDictionaries[0] =
      (ResourceDictionary)Application.LoadComponent(
         new Uri(@"\WpfThemes;component\White.xaml", UriKind.Relative)));

   ...
}

Wenn nun die weiße Schaltfläche geklickt wird ich den Knopf in dem Usercontrol weiß zu drehen erwarten würde, und wenn die Schwarz-Schaltfläche geklickt wird Ich würde erwarten, dass die Taste schwarz machen. Dies geschieht nicht, aber.

Weiß jemand, warum? Gibt es eine Lösung?

Edit: Idee. Vielleicht, wenn es eine Möglichkeit gibt Neubewertung von Dynamic zu erzwingen, wenn die Themenwechsel, das würde funktionieren

Danke, Dusty

War es hilfreich?

Lösung

Ich denke, das ein übersehenes Problem im WPF-Rahmen sein kann.

Von dem, was ich über Reflector sagen kann, scheint es, dass, wenn das Application Ressourcenverzeichnis katastrophal geändert wird (eine Änderung, die wahrscheinlich breit wird hat reichende Auswirkungen wie das Hinzufügen, Entfernen oder eine Haut zu ersetzen), gibt Code, der über alle Schleifen sie den Windows in der Anwendung und Kräften neu bewerten ihre DynamicResources. Aber auch andere Elemente, die ich halten Top-Level in WPF wie ElementHosts nicht die gleiche Behandlung erhalten. Dies führt zu dem Verhalten, das ich erlebe.

Meine Abhilfe für dieses Problem ist, manuell durch all meine ElementHosts gehen individuell und hinzuzufügen, zu entfernen oder die Haut ResourceDictionary Datei zu ersetzen. Es ist nicht perfekt, aber es wird die Arbeit erledigt.

Andere Tipps

Eine andere Lösung wäre, ein Dummy-Fenster zu erstellen und den Inhalt des Element als Inhalt angeben. Wenn Sie die Anwendung schauen und überprüfen, wie es Änderungen von resourcedictionaries behandelt, sehen Sie, dass es nur Fenster informiert ..

Das einzige, was Sie daran erinnern sollen, ist zu zeigen, nie das Fenster (-> Ausnahme), und es zu schließen, wenn das Element entsorgen, so kann die Anwendung Abschaltung richtig

.
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top