我认为您需要查看 WPF 应用程序中的主题。程序集可以包含以下几行:
[程序集:ThemeInfo(ResourceDictionaryLocation.SourceAssembly , ResourceDictionaryLocation.SourceAssembly)]
这意味着应用程序的系统主题位于您的程序集中(在文件夹 /themes 中)。主题名称必须符合系统主题...例如:
The Aero theme (Windows Vista and Windows 7): themes\Aero.NormalColor.xaml
The default Windows XP theme: themes\Luna.NormalColor.xaml
The olive green Windows XP theme: themes\Luna.Homestead.xaml
The Windows Classic theme: themes\Classic.xaml
当用户更换系统皮肤时,WPF 应用程序会自动下载您的主题。相应地,您可以为每个系统主题设置控制模板。更多信息可参见:
“亚当·内森。WPF 4 释放”。第 14 章。
主题化 WPF 应用程序:http:
//blogs.infosupport.com/theming-wpf-applications/
我希望这有帮助。
* 编辑 *
我发现了一个有趣的例子,其中提到了实际的变化主题:
http://northhorizon.net/2010/how-to-actually-change-the-system-theme-in-wpf/
您可以设置显式样式,它不会响应系统中的皮肤更改:
<Style x:Key="ExplicitGreenButtonStyle" TargetType="Button" BasedOn="{StaticResource {x:Type Button}}">
<Setter Property="Background" Value="Green" />
<Setter Property="Foreground" Value="White" />
</Style>
因此,隐式样式将响应更改系统皮肤:
<Style x:Key="ImplicitGreenButtonStyle" TargetType="Button">
<Setter Property="Background" Value="Green" />
<Setter Property="Foreground" Value="White" />
</Style>
此外,在示例中包含一个有用的代码ThemeHelper,其中一些主题功能。
* 编辑 #2 *
如果我理解正确,首先您需要获取系统主题名称。此操作可以通过多种方式完成。
第一个是使用库“UxTheme.dll”中的 Win32 函数,例如GetCurrentThemeName():
[DllImport("uxtheme.dll", CharSet = CharSet.Auto)]
public static extern int GetCurrentThemeName(StringBuilder pszThemeFileName, int dwMaxNameChars, StringBuilder pszColorBuff, int dwMaxColorChars, StringBuilder pszSizeBuff, int cchMaxSizeChars);
StringBuilder stringThemeName = new StringBuilder(260);
StringBuilder stringColorName = new StringBuilder(260);
StringBuilder stringSizeName = new StringBuilder(260);
Int32 s = GetCurrentThemeName(stringThemeName, 260, stringColorName, 260, stringSizeName, 260);
但是我这个功能没有正确接收到一些系统主题名称,比如“经典”。所以我尝试了不同的方法。
第二种方法是从注册表中获取主题名称。在路径“HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Themes\LastTheme”中包含当前系统主题。那么我们是否需要通过窗口挂钩拦截“更改系统主题事件”。
下面是一个带有几个按钮的示例,样式因系统主题而异:
添加到窗口:
SourceInitialized="Window_SourceInitialized"
款式:
<Style x:Key="DefaultStyle" BasedOn="{StaticResource {x:Type Button}}" TargetType="{x:Type Button}">
<Setter Property="Background" Value="CadetBlue" />
</Style>
<Style x:Key="LunaStyle" TargetType="{x:Type Button}">
<Setter Property="Background" Value="Blue" />
<Setter Property="Foreground" Value="White" />
</Style>
<Style x:Key="ClassicStyle" TargetType="{x:Type Button}">
<Setter Property="Background" Value="Gray" />
<Setter Property="Foreground" Value="Black" />
</Style>
主网格:
<Grid>
<Button Style="{StaticResource DefaultStyle}" Content="Default button" Width="100" Height="30" VerticalAlignment="Top" HorizontalAlignment="Left" />
<Button Name="ChangeButtonStyle" Content="Changes style" Width="100" Height="30" VerticalAlignment="Top" HorizontalAlignment="Right" />
<TextBlock Name="CurrentTheme" FontSize="16" Text="Null" Width="150" Height="30" HorizontalAlignment="Center" VerticalAlignment="Top" />
</Grid>
在代码中:
拦截“更改系统主题事件”:
private IntPtr hwnd;
private HwndSource hsource;
private void Window_SourceInitialized(object sender, EventArgs e)
{
if ((hwnd = new WindowInteropHelper(this).Handle) == IntPtr.Zero)
{
throw new InvalidOperationException("Could not get window handle.");
}
hsource = HwndSource.FromHwnd(hwnd);
hsource.AddHook(WndProc);
}
private IntPtr WndProc(IntPtr hwnd, int msg, IntPtr wParam, IntPtr lParam, ref bool handled)
{
switch (msg)
{
case 0x31A: // Define this as WM_DWMCOMPOSITIONCHANGED for Windows 7
case 0x31E: // Define this as WM_THEMECHANGED
// Action on the change system theme
GetThemeName(SubKey, Value);
return IntPtr.Zero;
default:
return IntPtr.Zero;
}
}
获取系统主题名称和设置样式:
public string SubKey = "Software\\Microsoft\\Windows\\CurrentVersion\\Themes\\LastTheme";
public string Value = "ThemeFile";
private void GetThemeName(string OpenKey, string Value)
{
RegistryKey pRegKey = Registry.CurrentUser;
pRegKey = pRegKey.OpenSubKey(OpenKey);
Object val = pRegKey.GetValue(Value);
string NameThemeFile = val as string;
if (NameThemeFile.IndexOf("Luna") != -1)
{
ChangeButtonStyle.Style = this.FindResource("LunaStyle") as Style;
CurrentTheme.Text = "Luna";
}
if (NameThemeFile.IndexOf("Classic") != -1)
{
ChangeButtonStyle.Style = this.FindResource("ClassicStyle") as Style;
CurrentTheme.Text = "Classic";
}
}
这种方法不是最好的,但会开始。