Stil

“Styles” in WPF zur Laufzeit austauschen. Mit dieser kleinen Demo will ich zeigen wie man es machen könnte.

Das Demoprojekt zeigt ein Fenster mit 4 Buttons. Die ersten beiden Schaltflächen wechseln den globalen Stil, der sich dann auf alle Schaltflächen auswirkt. Die erste Schaltfläche lädt einen Stil von einer auf der Festplatte abgelegten xaml-Datei nach, die zweite einen Stil aus den im Projekt  enthaltenen Resourcen.
Die dritte Schaltfläche setzt einen Stil für sich alleine und die vierte setzt alles wieder auf den Orginalzustand.

Beginnen wir mit dem Fenster:

<Window.Resources>
    <Style x:Key="Style1" />
</Window.Resources>
<StackPanel>
    <Button Style="{DynamicResource GlobalStyle}" Height="33" Margin="10"
        Name="btnStyle1" Click="btnStyle1_Click">GlobalStyle 1</Button>
    <Button Style="{DynamicResource GlobalStyle}" Height="33" Margin="10"
        Name="btnStyle2" Click="btnStyle2_Click">GlobalStyle 2</Button>
    <Button Style="{DynamicResource GlobalStyle}" Height="33" Margin="10"
        Name="btnIndividualStyle" Click="btnIndividualStyle_Click">IndividualStyle</Button>
    <Button Style="{DynamicResource GlobalStyle}" Height="33" Margin="10"
        Name="btnReset" Click="btnReset_Click">Reset</Button>
</StackPanel>

Jeder Button erhält über die Style-Eigenschaft eine Verweis auf eine “DynamicResource”, die leer ist. Dadurch werden die Schaltflächen ganz normal in Ihrem regulären Systemstil angezeigt.

Nun zum Laden und wechseln der Stile. Im folgende Codeabschnitt wird ein xaml-ResourceDictionary von der Festplatte nachgeladen und dem globalen Stil zugewiesen.

private void btnStyle1_Click(object sender, RoutedEventArgs e)
{
    ResourceDictionary style;

    using (FileStream fs = new FileStream("GlobalStyle1.xaml", FileMode.Open,
        FileAccess.Read))
    {
        style = (ResourceDictionary)XamlReader.Load(fs);
        this.Resources = style;
        fs.Close();
    }

    if (null != style)
    {
        this.Resources = style;
    }
}

Das ResourceDictionary enthält dabei folgenden xaml-Code:

Nach Betätigen der Schaltfläche erhalten alle Schaltfläche einen roten Hintergrund.

Schaltfläche 2 lädt die Resourcen nun nicht von der Platte, sondern aus den Programmresourcen:

private void btnStyle2_Click(object sender, RoutedEventArgs e)
{
    ResourceDictionary style2 = new ResourceDictionary();

    style2.Source =
        new Uri("/DynamicStyleLoader;component/GlobalStyle2.xaml",
            UriKind.RelativeOrAbsolute);

    this.Resources = style2;
}

Nach Betätigen der Schaltfläche erhalten alle Schaltfläche einen grünen Hintergrund.

Einen individuellen Style für nur eine Schaltfläche läßt sich so zuweisen:

private void btnIndividualStyle_Click(object sender, RoutedEventArgs e)
{
    ResourceDictionary indStyle = new ResourceDictionary();

    indStyle.Source =
        new Uri("/DynamicStyleLoader;component/IndividualStyle.xaml",
            UriKind.RelativeOrAbsolute);          

    this.btnIndividualStyle.Style = (Style)indStyle["IndividualStyle"];
}

Nach Betätigen der Schaltfläche erhält genau die Schaltfläche einen blauen Hintergrund.

Um alles wieder auf Standard zurückzusetzen reicht es, die Resourcen des aktuellen Fensters (this) wieder zu “nullen”. Allerdings muss für die Schaltfläche mit dem individuellen Stile, sofern man ihr diesen durch betätigen der Schaltfläche vorher zugewiesen hat, die “ResourceReference” zum globalen Stil wiederhergestellt werden.

private void btnReset_Click(object sender, RoutedEventArgs e)
{
    this.Resources = null;
    this.btnIndividualStyle.SetResourceReference(Button.StyleProperty,
        "GlobalStyle");
}

Fertig.