Изменить стиль wpf во время работы программы - PullRequest
0 голосов
/ 28 апреля 2018

Это то, что я положил в свой app.xaml, который я использую во многих местах в своем коде:

<Style x:Key="windowStyleDefault">
    <Setter Property="Control.Background" Value="#F0F0F0" />
    <Setter Property="Control.Foreground" Value="#179DD1" />
</Style>

Я хочу изменить шрифты и цвета всего приложения (давайте начнем с цвета):

<Menu  Style="{DynamicResource windowStyleDefault}" >
    <MenuItem Header="File" >
        <MenuItem x:Name="NewFarmReport" Header="New Farm Report" Click="NewFarmReport_Click"/>
        <Separator/>
        <MenuItem x:Name="Exit" Header="Exit" Click="Exit_Click"/>
    </MenuItem>
    <MenuItem Header="Settings">
        <MenuItem x:Name="GuiSettings" Header="GUI Settings" Click="GuiSettings_Click"/>
        <MenuItem x:Name="CurrentWeightSettings" Header="Current Weights Settings" Click="CurrentWeightSettings_Click"/>
        <MenuItem x:Name="DefaultWeightSettings" Header="Default Weights Settings" Click="DefaultWeightSettings_Click"/>
    </MenuItem>
    <MenuItem Header="View">
        <MenuItem Header="Show History" x:Name="ShowHistory" Click="ShowHistory_Click"/>
    </MenuItem>
    <MenuItem Header="Compare" x:Name="CompateBtn" Click="CompateBtn_Click">
    </MenuItem>
</Menu>

в этом коде я объявляю меню, используя windowStyleDefault:

<Grid DockPanel.Dock="Top" Style="{StaticResource windowStyleDefault}">
    <Grid.ColumnDefinitions>
        <ColumnDefinition Width="6*"/>
        <ColumnDefinition />
        <ColumnDefinition />
    </Grid.ColumnDefinitions>    
    <Label FontStretch="Normal" FontWeight="Bold" FontSize="17" DockPanel.Dock="Top" Content="Report History" Style="{StaticResource windowStyleDefault }" Margin="0,0,2,2" />    
    <Image x:Name="OpenSlectionMode" Margin="0,0,6,-0.4" MouseEnter="OpenSlectionMode_MouseEnter" MouseLeave="OpenSlectionMode_MouseLeave"
                           MouseLeftButtonDown="OpenSlectionMode_MouseLeftButtonDown" MaxWidth="30" MaxHeight="30" Grid.ColumnSpan="2" HorizontalAlignment="Right" Width="16"
                           Source="{StaticResource selection}"/>    
    <Image x:Name="ClosdeHistoryImage" Margin="0,0,6,-0.4" MouseLeftButtonDown="CloseHistoryImage_MouseLeftButtonDown" 
                           MouseEnter="CloseHistoryImage_MouseEnter" MouseLeave="CloseHistoryImage_MouseLeave"
                           MaxWidth="20" MaxHeight="20" Grid.ColumnSpan="3" HorizontalAlignment="Right" Width="16"
                           Source="{StaticResource CloseHistoryNormal}"/>    
</Grid>

и здесь я использую для DockPanel.

Ответы [ 2 ]

0 голосов
/ 30 апреля 2018

Существует один известный мне подход: ResourceDictionary, очень простой и полезный во многих случаях, например, для многоязычного использования вашего приложения или добавления тем.

Прежде всего, для каждой темы, которую вы хотите добавить, вы должны добавить ResourceDictionary в ваш проект и определить стили, шрифты или кисти или любые ресурсы, которые вы хотите использовать в качестве темы, в этом конкретном ResourceDictionary.

Пример (MyFirstTheme.xaml):

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

    <FontFamily x:Key="MyFont">Segoe UI</FontFamily>
    <SolidColorBrush x:Key="MyThemeColor" Color="#FF34495E"/>

</ResourceDictionary>

Пример (MySecondTheme.xaml):

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

    <FontFamily x:Key="MyFont">Tahoma</FontFamily>
    <SolidColorBrush x:Key="MyThemeColor" Color="#D89A9E"/>

</ResourceDictionary>

Вы должны добавить словари ресурсов как можно больше тем. И для того, чтобы установить один по умолчанию, вы должны указать его в файле App.xaml следующим образом:

<Application x:Class="MyApp.App"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             StartupUri="MainWindow.xaml">

    <Application.Resources>
        <ResourceDictionary>
            <ResourceDictionary.MergedDictionaries>

                <ResourceDictionary Source="Themes\MyFirstTheme.xaml"/> 
                // This will be the default theme

            </ResourceDictionary.MergedDictionaries>
        </ResourceDictionary>
    </Application.Resources>
</Application>

Для назначения темы на объекты или элементы управления, вы должны сделать следующее:

<Window x:Name="window" x:Class="MyApp.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        Title="MyApp" Height="400" Width="400"  FontFamily="{DynamicResource MyFont}">

        <Grid>
                <TextBlock Foreground="{DynamicResource MyThemeColor}" Text="Theme Test" />
        </Grid>
</Window>

Примечание. При использовании ресурсов в элементах управления или объектах привязка должна быть определена как DynamicResource

Предположим, что вы добавили все словари тем и хотите переключаться между ними в коде, используйте эту функцию:

public void ChangeTheme(string ThemeName)
{
     ResourceDictionary dict = new ResourceDictionary();
                dict.Source = new Uri("..\\Themes\\" + ThemeName + ".xaml", UriKind.Relative);
                App.Current.Resources.MergedDictionaries.Add(dict);
}

Использование:

 ChangeTheme("MySecondTheme");
 UpdateLayout();
0 голосов
/ 28 апреля 2018

Кажется, там есть часть этого.
Если вы используете динамический ресурс:

<Menu  Style="{DynamicResource windowStyleDefault}" >

Тогда он поймает изменение в windowStyleDefault. Должно быть, все это заменяется.
Вы можете сделать это как минимум двумя способами.
Вы можете объединить в другом словаре ресурсов в application.current.resources ИЛИ ресурсы элемента управления в области, содержащей, где вы хотите применить изменение. Если в этом словаре ресурсов есть запись с тем же ключом и другим материалом, он изменится.
Или вы можете сделать это в коде.

Идите, получите стиль, где хотите, и установите его:

Application.Current.Resources["windowStyleDefault"] = yourNewStyle;

Если вы вместо этого использовали staticresource, тогда изменения не будут приниматься.

Подходит ли что-нибудь из того, что вы бы назвали подходящим, я могу только догадываться.

...