Как заставить стили WPF переключаться во время выполнения?

У меня есть ресурсы стиля в WPF, чтобы в моем App.xaml я мог определить, используется ли клиент или макет администратора. Это хорошо работает, получив весь стиль из основного XAML в стиле HTML/CSS.

Как мне сделать эту динамическую, чтобы я мог нажать кнопку в приложении и переключить макет между клиентом и администратором во время выполнения?

Добавление:

Спасибо Meeh за ссылки, поэтому я сделал это, и когда я отлаживаю, он проходит через все строки, но по-прежнему не меняет макет, что еще мне нужно сделать, чтобы изменения макета во время выполнения?

private void Button_Switch_Layout_Click(object sender, RoutedEventArgs e)
{
    string layoutIdCode = "administrator";

    switch (layoutIdCode)
    {
        case "administrator":
            langDictPath = "Resources/AdministratorLayout.xaml";
            break;

        case "customer":
            langDictPath = "Resources/CustomerLayout.xaml";
            break;
    }

    Uri langDictUri = new Uri(langDictPath, UriKind.Relative);
    ResourceDictionary langDict = Application.LoadComponent(langDictUri) as ResourceDictionary;
    Application.Current.Resources.MergedDictionaries.Clear();
    Application.Current.Resources.MergedDictionaries.Add(langDict);
}

 

Оригинальный код:


App.xaml:

<Application x:Class="TestMvvm8837.App"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    StartupUri="Window1.xaml">
    <Application.Resources>
        <ResourceDictionary>
            <ResourceDictionary.MergedDictionaries>
                <ResourceDictionary Source="Resources/CustomerLayout.xaml"/>
            </ResourceDictionary.MergedDictionaries>
        </ResourceDictionary>
    </Application.Resources>
</Application>

Window1.xaml:

<Window x:Class="TestMvvm8837.Window1"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    Style="{StaticResource MainWindow}"
    Title="Resource Test" >
    <DockPanel>

        <Grid Style="{StaticResource Form}">
            <Grid.RowDefinitions>
                <RowDefinition Height="Auto" />
                <RowDefinition Height="Auto" />
                <RowDefinition Height="Auto" />
                <RowDefinition Height="Auto" />
            </Grid.RowDefinitions>
            <Grid.ColumnDefinitions>
                <ColumnDefinition Width="Auto" />
                <ColumnDefinition Width="Auto" />
            </Grid.ColumnDefinitions>

            <TextBlock Style="{StaticResource FormLabel}" Grid.Column="0" Grid.Row="0" Text="First Name" />
            <TextBlock Style="{StaticResource FormLabel}" Grid.Column="0" Grid.Row="1" Text="Last Name" />
            <TextBlock Style="{StaticResource FormLabel}" Grid.Column="0" Grid.Row="2" Text="E-Mail" />

            <TextBox Grid.Column="1" Grid.Row="0"/>
            <TextBox Grid.Column="1" Grid.Row="1"/>
            <TextBox Grid.Column="1" Grid.Row="2"/>

            <Button Style="{StaticResource FormSaveButton}" Grid.Column="1" Grid.Row="3" Content="Save"/>

        </Grid>

    </DockPanel>
</Window>

AdministratorLayout.xaml:

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

    <Style x:Key="MainWindow" TargetType="{x:Type Window}">
        <Setter Property="Width" Value="800"/>
        <Setter Property="Height" Value="600"/>
    </Style>

    <Style x:Key="Form" TargetType="{x:Type Grid}">
        <Setter Property="Margin" Value="20"/>
    </Style>

    <Style x:Key="FormLabel" TargetType="{x:Type TextBlock}">
        <Setter Property="Margin" Value="10"/>
        <Setter Property="FontFamily" Value="Verdana"/>
        <Setter Property="FontSize" Value="14"/>
    </Style>

    <Style TargetType="{x:Type TextBox}">
        <Setter Property="Margin" Value="10"/>
        <Setter Property="Width" Value="200"/>
        <Setter Property="HorizontalAlignment" Value="Left"/>
        <Setter Property="VerticalAlignment" Value="Top"/>
    </Style>

    <Style x:Key="FormSaveButton" TargetType="{x:Type Button}">
        <Setter Property="Margin" Value="10"/>
        <Setter Property="FontFamily" Value="Verdana"/>
        <Setter Property="FontSize" Value="14"/>
        <Setter Property="Width" Value="100"/>
        <Setter Property="HorizontalAlignment" Value="Left"/>
        <Setter Property="VerticalAlignment" Value="Top"/>
        <Setter Property="Cursor" Value="Hand"/>
    </Style>

</ResourceDictionary>

CustomerLayout.xaml:

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

    <Style x:Key="MainWindow" TargetType="{x:Type Window}">
        <Setter Property="Width" Value="600"/>
        <Setter Property="Height" Value="480"/>
        <Setter Property="Background">
            <Setter.Value>
                <LinearGradientBrush EndPoint="1.156,1.133" StartPoint="-0.033,0.019">
                    <GradientStop Color="#FFFFFFFF" Offset="0"/>
                    <GradientStop Color="#FF4FADD3" Offset="1"/>
                </LinearGradientBrush>
            </Setter.Value>
        </Setter>
    </Style>

    <Style x:Key="Form" TargetType="{x:Type Grid}">
        <Setter Property="Margin" Value="5"/>
    </Style>

    <Style x:Key="FormLabel" TargetType="{x:Type TextBlock}">
        <Setter Property="Margin" Value="10"/>
        <Setter Property="FontFamily" Value="Verdana"/>
        <Setter Property="FontSize" Value="10"/>
    </Style>

    <Style TargetType="{x:Type TextBox}">
        <Setter Property="Margin" Value="10"/>
        <Setter Property="Width" Value="200"/>
        <Setter Property="HorizontalAlignment" Value="Left"/>
        <Setter Property="VerticalAlignment" Value="Top"/>
    </Style>

    <Style x:Key="FormSaveButton" TargetType="{x:Type Button}">
        <Setter Property="Margin" Value="10"/>
        <Setter Property="FontFamily" Value="Verdana"/>
        <Setter Property="FontSize" Value="10"/>
        <Setter Property="Width" Value="100"/>
        <Setter Property="HorizontalAlignment" Value="Left"/>
        <Setter Property="VerticalAlignment" Value="Top"/>
        <Setter Property="Cursor" Value="Hand"/>
    </Style>

</ResourceDictionary>

Ответ 1

Вам нужно использовать DynamicResource внутри Window1.xaml вместо StaticResource. StaticResource оценивается только один раз, тогда как DynamicResource фактически прослушивает изменения.

Ответ 2

Вы должны:

  • Загрузите словарь ресурсов, используя XamlReader, в котором вы определили новый стиль
  • Получить ссылку на новый стиль из загруженного ресурса (newStyle = (Style) resource ["styleName])
  • Установите новый стиль в элементе управления: control.Style = newStyle

НТН

до свидания

Ответ 3

Вы можете использовать ContentControl - здесь он изменяет xaml на основе переменной ViewType.

<ContentControl Style="{StaticResource ScriptsViewTemplate}" VerticalAlignment="Stretch" />   


<Style x:Key="ScriptsViewTemplate" TargetType="ContentControl">
<Style.Triggers>
  <DataTrigger Binding="{Binding Path = ViewType,Mode=TwoWay}" Value="True">
    <Setter Property="Template" Value="{StaticResource ScriptsTreeViewTemplate}"/>
  </DataTrigger>
  <DataTrigger Binding="{Binding Path = ViewType,Mode=TwoWay}" Value="False">
    <Setter Property="Template" Value="{StaticResource ScriptsListViewTemplate}"/>
  </DataTrigger>
</Style.Triggers>
</Style>