C# 装订风格属性';ResourceDictionary中的s值转换为ViewModel属性
我正在尝试更改WPF应用程序的样式(FontFamily、FontSize等)。所以搜索没有成功。 在应用程序中,我使用MVVM模式。为了给我的应用程序一个统一的外观,我使用ResourceDictionary来定义不同的样式和外观。到目前为止,这是可行的。我想实现的是通过运行时使用样式窗口更改单个属性:C# 装订风格属性';ResourceDictionary中的s值转换为ViewModel属性,c#,wpf,xaml,mvvm,C#,Wpf,Xaml,Mvvm,我正在尝试更改WPF应用程序的样式(FontFamily、FontSize等)。所以搜索没有成功。 在应用程序中,我使用MVVM模式。为了给我的应用程序一个统一的外观,我使用ResourceDictionary来定义不同的样式和外观。到目前为止,这是可行的。我想实现的是通过运行时使用样式窗口更改单个属性: <Window x:Class="StyleResourceDictionariesDemo.View.StyleWindow" xmlns="http://sc
<Window x:Class="StyleResourceDictionariesDemo.View.StyleWindow"
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"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d"
Title="StyleWindow" Height="450" Width="800"
Style="{DynamicResource WindowStyle}">
<Window.Resources>
<ResourceDictionary Source="../ResourceDictionaries/Styles/Controls/WindowStyle.xaml"/>
</Window.Resources>
<StackPanel Orientation="Vertical">
<StackPanel Orientation="Horizontal" HorizontalAlignment="Left">
<TextBlock Height="20" Width="75" Text="FontFamily:" Margin="10" TextAlignment="Right"/>
<ComboBox x:Name="CbFonts" Width="200" Margin="10,10,7,0"
ItemsSource="{Binding Source={x:Static Fonts.SystemFontFamilies}}" SelectedItem="{Binding OwnFontFamily, UpdateSourceTrigger=PropertyChanged}"
SelectedValuePath="Source" Height="23" VerticalAlignment="Top">
<ComboBox.ItemTemplate>
<DataTemplate>
<TextBlock Text="{Binding}" FontFamily="{Binding}" Height="20"/>
</DataTemplate>
</ComboBox.ItemTemplate>
</ComboBox>
</StackPanel>
<Border Height="2" Width="Auto" Background="Red" HorizontalAlignment="Stretch" VerticalAlignment="Center"/>
<StackPanel Orientation="Horizontal" HorizontalAlignment="Left">
<TextBlock Height="20" Width="50" Text="Size:" Margin="10" TextAlignment="Right"/>
<Slider Style="{DynamicResource SliderStyle}" Width="100" x:Name="FontSizeSlider" Value="{Binding OwnFontSize, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"
Minimum="{Binding OwnSmallFontSize}" Maximum="{Binding OwnBigFontSize}" TickPlacement="Both" Margin="10" TickFrequency="{Binding OwnFontSizeSteps}" IsSnapToTickEnabled="True"/>
<TextBlock Height="20" Width="50" Text="{Binding ElementName=FontSizeSlider, Path=Value, UpdateSourceTrigger=PropertyChanged}" TextAlignment="Right"/>
</StackPanel>
</StackPanel>
</Window>
此外,我还创建了一个ControlBaseStyle xaml文件,其他所有样式都从该文件继承:
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:viewModel="clr-namespace:StyleResourceDictionariesDemo.ViewModel">
<viewModel:StyleWindowViewModel x:Key="StyleWindowViewModel" />
<Style TargetType="{x:Type Control}" x:Key="ControlBaseStyle">
<Style.Setters>
<Setter Property="FontFamily" Value="{DynamicResource OwnFontFamily}"/>
<Setter Property="FontStyle" Value="{DynamicResource FontStyleKey}"/>
<Setter Property="FontWeight" Value="{DynamicResource FontWeightKey}"/>
<Setter Property="FontSize" Value="{DynamicResource OwnFontSize}"/>
<Setter Property="Background" Value="{DynamicResource SystemBackground}"/>
<Setter Property="Foreground" Value="{DynamicResource SystemForeground}"/>
</Style.Setters>
</Style>
</ResourceDictionary>
我遇到的问题是controlbasestyle无法识别来自ViewModel属性的更改,我目前不知道原因。也许我错过了一些简单的事情,我只是看不到,或者我采取了错误的方法来解决这个问题
提前谢谢
米尔科
编辑1:
我的目标是在运行时更改样式和外观。
结构如下:
最初,所有样式都由蒙皮指定不同的特性。
皮肤定义了应用程序中应该一致的颜色、字体、大小和其他内容。可以通过它们的特定名称(用x:key定义)调用它们。
该样式使用当前使用的setter的名称(例如,属性background的value=-dynamicResourceSystemBackground)检索蒙皮上方定义的值。到目前为止还不错
目标是使用MVVM模式实现这一点。我已经定义了一个样式窗口和一个视图模型(上面的代码)。但是我不能让这种风格注意到这种变化
现在的第一个问题是,是否可以,如果可以,如何在运行时更改FontFamily(或任何其他属性)的值。
第二个问题是,这种方法在现实生活中是正确的,还是有更好的方法
皮肤示例:
LightSkin.xaml:
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation">
<ResourceDictionary.MergedDictionaries>
<!--Default Style-->
<ResourceDictionary Source="../00_Default/DefaultStyle.xaml"/>
<!--Specific Style-->
<ResourceDictionary Source="LightColor.xaml"/>
<ResourceDictionary Source="LightSizes.xaml"/>
<ResourceDictionary Source="LightFont.xaml"/>
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
DefaultStyle.xaml:
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation">
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="../../Styles/Controls/ButtonStyle.xaml"/>
<ResourceDictionary Source="../../Styles/Controls/LabelStyle.xaml"/>
<ResourceDictionary Source="../../Styles/Controls/ToggleButtonStyle.xaml"/>
<ResourceDictionary Source="../../Styles/Controls/WindowStyle.xaml"/>
</ResourceDictionary.MergedDictionaries>
LightSkin.xaml:
DefaultStyle.xaml:
LabelBaseStyle.xaml:
每个(基本)样式都直接或间接继承自ControlBaseStyle.xaml(上面的代码)。您应该将ControlBaseStyle的设置器绑定到视图模型的属性:
<viewModel:StyleWindowViewModel x:Key="StyleWindowViewModel" />
<Style TargetType="{x:Type Control}" x:Key="ControlBaseStyle">
<Style.Setters>
<Setter Property="FontFamily" Value="{Binding OwnFontFamily, Source={StaticResource StyleWindowViewModel}}"/>
...
</Style.Setters>
</Style>
...
另外,当您想要更改样式时,请确保设置在ResourceDictionary
中定义的实际StyleWindowViewModel
实例的属性。您可以参考我的。尝试将BaseStyle目标设置为FrameworkElement,并将setter属性设置为TextBlock.FontSize。这应该对fontsize有所帮助。谢谢你的评论,但我想要实现的是不可行的,因为我一开始就认为它是可行的。我必须走一条不同的道路来实现我所面临的一切。所以我现在正在研究如何实现它的另一个解决方案。谢谢你的回复,我明天会仔细看看,但是快速复制粘贴代码片段并没有带来任何进展。但你得到了我想要做的。我网站的高级开发人员表示,这不可能是我想要做的,或者这很复杂。什么是复杂的?如何以及何时设置StyleWindowViewModel
的属性?你能提供一个答案吗?@Mirko:你还没有展示你如何修改setter应该绑定到的视图模型的属性。很抱歉我的回复太晚了,mm8,我正在研究另一种方法来解决这个问题。当我完成时,我将分享这个。
LabelBaseStyle.xaml:
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="ControlBaseStyle.xaml"/>
</ResourceDictionary.MergedDictionaries>
<Style TargetType="{x:Type Label}" x:Key="LabelBaseStyle" BasedOn="{StaticResource ControlBaseStyle}">
<Style.Setters>
<Setter Property="Width" Value="300"/>
<Setter Property="Height" Value="150"/>
<Setter Property="HorizontalAlignment" Value="Center"/>
<Setter Property="VerticalAlignment" Value="Top"/>
<Setter Property="Content" Value="{Binding Content}"/>
</Style.Setters>
</Style>
</ResourceDictionary>
<viewModel:StyleWindowViewModel x:Key="StyleWindowViewModel" />
<Style TargetType="{x:Type Control}" x:Key="ControlBaseStyle">
<Style.Setters>
<Setter Property="FontFamily" Value="{Binding OwnFontFamily, Source={StaticResource StyleWindowViewModel}}"/>
...
</Style.Setters>
</Style>