我想你需要在WPF应用程序中看到主题。组件可包含以下行:
[组件:ThemeInfo(ResourceDictionaryLocation SourceAssembly, ResourceDictionaryLocation.SourceAssembly)]
这意味着应用程序的系统的主题位于您组件(在文件夹/主题) 。主题名称必须符合系统主题...例如:
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应用程序会自动下载你的主题。因此,您可以为每个系统主题设置控制模板。更多信息可以在:
“Adam Nathan。WPF 4 Unleashed”。第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”像GetCurrentThemeName()使用Win32函数:
[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";
}
}
这种方法是不是最好的,但将开始。
每当有人推荐分配一个新的ControlTemplate来解决某些问题时,我完全停止阅读,因为这个问题总是立刻流入我的脑海。 – springy76 2016-05-04 08:11:57
您也可以为各种控件编写模板,以便您的应用程序及其所有控件在所有主题中看起来都一样 - 无论将来会有什么新主题。这就是例如我猜是微软Office。 – Lumo 2017-09-08 10:09:01