我有两个主题: Aero.NormalColor.xaml 和 Classic.xaml 。我的窗户上有按钮。
<Grid>
<Button Grid.Row="0"
Name="_first"
Content="Fisrt">
</Button>
</Grid>
我在bouth主题中为Button
定义了样式。
在 Aero.NormalColor.xaml :
中<Style TargetType="{x:Type ButtonBase}">
<Setter Property="Background" Value="Red"/>
</Style>
在 Classic.xaml :
中<Style TargetType="{x:Type ButtonBase}">
<Setter Property="Background" Value="Violet"/>
</Style>
并像这样设置汇编属性。
[assembly: ThemeInfo(ResourceDictionaryLocation.SourceAssembly,
ResourceDictionaryLocation.SourceAssembly)]
我希望选择 Aero 主题时 - 按钮将为Red
,当选择经典主题时,按钮将为Violet
。但没有任何反应。无论选择什么主题,按钮都有默认的Gray
颜色。我做错了什么?
答案 0 :(得分:1)
解。事实证明,它比我想象的更复杂,但现在它有效。
首先创建一个派生按钮:
public partial class ImageButton : Button
{
// Very important!
static ImageButton()
{
DefaultStyleKeyProperty.OverrideMetadata(
typeof(ImageButton),
new FrameworkPropertyMetadata(typeof(ImageButton)));
}
public ImageButton()
{
InitializeComponent();
}
}
<Button x:Class="TestProjectTheme.ImageButton"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
</Button>
其次,正确设置程序集属性:
[assembly: ThemeInfo(ResourceDictionaryLocation.SourceAssembly,
ResourceDictionaryLocation.SourceAssembly)]
第三,为windows主题定义资源词典:
<强> Aero.NormalColor.xaml 强>
<Style TargetType="{x:Type Local:ImageButton}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type Local:ImageButton}">
<Border Background="Aquamarine">
<ContentPresenter
Margin="{TemplateBinding Padding}"
HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}"
VerticalAlignment="{TemplateBinding VerticalContentAlignment}"
RecognizesAccessKey="True"/>
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<强> Classic.xaml 强>
<Style TargetType="{x:Type Local:ImageButton}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type Local:ImageButton}">
<Border Background="Red">
<ContentPresenter
Margin="{TemplateBinding Padding}"
HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}"
VerticalAlignment="{TemplateBinding VerticalContentAlignment}"
RecognizesAccessKey="True"/>
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
第四,在 MainWindow 中定义 ImageButton :
<Local:ImageButton Content="look here!"
Width="100"
Height="100">
</Local:ImageButton>
第五,在 Windows-&gt; Personalizaton 中运行应用程序并将主题从经典切换到 Aero ,反之亦然 第六 - 享受:)
答案 1 :(得分:0)
不幸的是,在WPF中切换主题的机制比看起来更复杂。 Here
你可以看到有关这方面的信息和解决方案,有些引用:
我越是想到这一点,我越发现所有这些问题都是由于我将系统主题(aero.normalcolor)应用于实际系统主题之上的风格而不是实际上改变它。所以我开始在Reflector中探索WPF如何选择当前主题。这听起来很难,而且实际上比它听起来要困难得多。经过十几个小时(分散了几个星期)和博客的一些指导非常接近(不幸的是,我的链接现在已经死了),我发现无论如何WPF在uxtheme.dll中调用本机方法获取实际的系统主题,然后将结果存储在
MS.Win32.UxThemeWrapper
,一个内部静态类(当然)。此外,类的属性是只读的(也标记为内部),因此更改它的最佳方法是直接操作私有字段。
通常,切换主题由“手”完成。
示例:
App.xaml
<Application.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="/Resources/Themes/DefaultSkin.xaml"/>
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
</Application.Resources>
App.xaml.cs
public partial class App : Application
{
public void ChangeTheme(Uri uri)
{
var resourceDict = Application.LoadComponent(uri) as ResourceDictionary;
Application.Current.Resources.MergedDictionaries.Clear();
Application.Current.Resources.MergedDictionaries.Add(resourceDict);
}
}
MainWindow.xaml
<StackPanel>
<Button Width="100" Height="100" Content="Test" />
<Button Width="100" Height="100" Content="Click Me" Click="Button_Click" />
</StackPanel>
MainWindow.xaml.cs
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
}
private void Button_Click(object sender, RoutedEventArgs e)
{
var app = App.Current as App;
app.ChangeTheme(new Uri(@"/Resources/Themes/BlueSkin.xaml", UriKind.Relative));
}
}
DefaultSkin.xaml
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<Style TargetType="{x:Type Button}">
<Setter Property="Background" Value="Red" />
</Style>
</ResourceDictionary>
BlueSkin.xaml
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<Style TargetType="{x:Type Button}">
<Setter Property="Background" Value="Blue" />
</Style>
</ResourceDictionary>