.net 使 WPF 应用程序看起来像 Metro 风格,即使在 Windows 7 中?(窗口铬/主题/主题)
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/13592326/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Making WPF applications look Metro-styled, even in Windows 7? (Window Chrome / Theming / Theme)
提问by Daniel
I like the window chrome on the new Office Suite and Visual Studio:
我喜欢新 Office 套件和 Visual Studio 上的窗口镶边:


I'm still developing applications for Windows 7 of course, but I'm wondering if there's a quick and easy way (read: WPF style or Windows Library) to emulate this style. I've done some window chrome styling in the past, but getting it to look and behave just right is really tricky.
当然,我仍在为 Windows 7 开发应用程序,但我想知道是否有一种快速简便的方法(阅读:WPF 样式或 Windows 库)来模拟这种样式。我过去做过一些窗口镀铬样式,但让它看起来和行为恰到好处真的很棘手。
Does anyone know if there are existing templates or libraries to add a "Modern UI" look and feel to my WPF applications?
有谁知道是否有现有的模板或库可以为我的 WPF 应用程序添加“现代 UI”外观?
采纳答案by Daniel
The solution I ended up choosing was MahApps.Metro(github), which (after using it on two pieces of software now) I consider an excellent UI kit (credit to Oliver Vogelfor the suggestion).
我最终选择的解决方案是MahApps.Metro( github),它(现在在两个软件上使用它之后)我认为这是一个出色的 UI 工具包(感谢Oliver Vogel的建议)。


It skins the application with very little effort required, and has adaptations of the standard Windows 8 controls. It's very robust.
它只需很少的工作即可为应用程序设置外观,并且对标准 Windows 8 控件进行了改编。它非常坚固。


A version is available on Nuget:
Nuget 上提供了一个版本:
You can install MahApps.Metro via Nuget using the GUI (right click on your project, Manage Nuget References, search for ‘MahApps.Metro') or via the console:
PM> Install-Package MahApps.Metro
您可以使用 GUI 通过 Nuget 安装 MahApps.Metro(右键单击您的项目,管理 Nuget 引用,搜索“MahApps.Metro”)或通过控制台:
PM> 安装包 MahApps.Metro
It's also free-- even for commercial use.
它也是免费的——即使用于商业用途。
Update 10-29-2013:
2013 年 10 月 29 日更新:
I discovered that the Github version of MahApps.Metro is packed with controls and styles that aren't available in the current nuget version, including:
我发现 MahApps.Metro 的 Github 版本包含了当前 nuget 版本中没有的控件和样式,包括:
Datagrids:
数据网格:


Clean Window:
清洁窗口:


Flyouts:
弹出窗口:


Tiles:
瓷砖:


The github repository is very active with quite a bit of user contributions. I recommend checking it out.
github 存储库非常活跃,有相当多的用户贡献。我建议检查一下。
回答by Kapitán Mlíko
What I did was creating my own Window and Style. Because I like to have control over everything and I didn't want some external libraries just to use a Window from it. I looked at already mentioned MahApps.Metro on GitHub
我所做的是创建自己的窗口和样式。因为我喜欢控制一切,而且我不希望一些外部库只是使用它的 Window。我在 GitHub 上查看了已经提到的MahApps.Metro


and also very nice Modern UI on GitHub. (.NET4.5 only)
以及GitHub 上非常漂亮的现代 UI。(仅限 .NET4.5)


There is one more it's Elysiumbut I really didn't try this one.
还有一个是Elysium,但我真的没有尝试过这个。


The style I did was really easy when I looked how it's done in these. Now I have my own Window and I can do whatever I want with xaml... for me it's the main reason why I did my own. And I made one more for you too :) I should probably say that I wouldn't be able to do it without exploring Modern UIit was great help. I tried to make it look like VS2012 Window. It looks like this.
当我看到它是如何完成这些时,我所做的风格真的很简单。现在我有了自己的窗口,我可以用 xaml 做任何我想做的事情……对我来说,这是我自己做的主要原因。我也为你做了一个 :) 我应该说,如果不探索现代用户界面,我将无法做到这一点,这是很大的帮助。我试图让它看起来像 VS2012 窗口。它看起来像这样。


Here is code (please note that it's targeting .NET4.5)
这是代码(请注意,它针对 .NET4.5)
public class MyWindow : Window
{
public MyWindow()
{
this.CommandBindings.Add(new CommandBinding(SystemCommands.CloseWindowCommand, this.OnCloseWindow));
this.CommandBindings.Add(new CommandBinding(SystemCommands.MaximizeWindowCommand, this.OnMaximizeWindow, this.OnCanResizeWindow));
this.CommandBindings.Add(new CommandBinding(SystemCommands.MinimizeWindowCommand, this.OnMinimizeWindow, this.OnCanMinimizeWindow));
this.CommandBindings.Add(new CommandBinding(SystemCommands.RestoreWindowCommand, this.OnRestoreWindow, this.OnCanResizeWindow));
}
private void OnCanResizeWindow(object sender, CanExecuteRoutedEventArgs e)
{
e.CanExecute = this.ResizeMode == ResizeMode.CanResize || this.ResizeMode == ResizeMode.CanResizeWithGrip;
}
private void OnCanMinimizeWindow(object sender, CanExecuteRoutedEventArgs e)
{
e.CanExecute = this.ResizeMode != ResizeMode.NoResize;
}
private void OnCloseWindow(object target, ExecutedRoutedEventArgs e)
{
SystemCommands.CloseWindow(this);
}
private void OnMaximizeWindow(object target, ExecutedRoutedEventArgs e)
{
SystemCommands.MaximizeWindow(this);
}
private void OnMinimizeWindow(object target, ExecutedRoutedEventArgs e)
{
SystemCommands.MinimizeWindow(this);
}
private void OnRestoreWindow(object target, ExecutedRoutedEventArgs e)
{
SystemCommands.RestoreWindow(this);
}
}
And here resources:
这里的资源:
<BooleanToVisibilityConverter x:Key="bool2VisibilityConverter" />
<Color x:Key="WindowBackgroundColor">#FF2D2D30</Color>
<Color x:Key="HighlightColor">#FF3F3F41</Color>
<Color x:Key="BlueColor">#FF007ACC</Color>
<Color x:Key="ForegroundColor">#FFF4F4F5</Color>
<SolidColorBrush x:Key="WindowBackgroundColorBrush" Color="{StaticResource WindowBackgroundColor}"/>
<SolidColorBrush x:Key="HighlightColorBrush" Color="{StaticResource HighlightColor}"/>
<SolidColorBrush x:Key="BlueColorBrush" Color="{StaticResource BlueColor}"/>
<SolidColorBrush x:Key="ForegroundColorBrush" Color="{StaticResource ForegroundColor}"/>
<Style x:Key="WindowButtonStyle" TargetType="{x:Type Button}">
<Setter Property="Foreground" Value="{DynamicResource ForegroundColorBrush}" />
<Setter Property="Background" Value="Transparent" />
<Setter Property="HorizontalContentAlignment" Value="Center" />
<Setter Property="VerticalContentAlignment" Value="Center" />
<Setter Property="Padding" Value="1" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type Button}">
<Grid Background="{TemplateBinding Background}">
<ContentPresenter x:Name="contentPresenter"
HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}"
VerticalAlignment="{TemplateBinding VerticalContentAlignment}"
SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}"
Margin="{TemplateBinding Padding}"
RecognizesAccessKey="True" />
</Grid>
<ControlTemplate.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="Background" Value="{StaticResource HighlightColorBrush}" />
</Trigger>
<Trigger Property="IsPressed" Value="True">
<Setter Property="Background" Value="{DynamicResource BlueColorBrush}" />
</Trigger>
<Trigger Property="IsEnabled" Value="false">
<Setter TargetName="contentPresenter" Property="Opacity" Value=".5" />
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<Style x:Key="MyWindowStyle" TargetType="local:MyWindow">
<Setter Property="Foreground" Value="{DynamicResource ForegroundColorBrush}" />
<Setter Property="Background" Value="{DynamicResource WindowBackgroundBrush}"/>
<Setter Property="ResizeMode" Value="CanResizeWithGrip" />
<Setter Property="UseLayoutRounding" Value="True" />
<Setter Property="TextOptions.TextFormattingMode" Value="Display" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="local:MyWindow">
<Border x:Name="WindowBorder" Margin="{Binding Source={x:Static SystemParameters.WindowNonClientFrameThickness}}" Background="{StaticResource WindowBackgroundColorBrush}">
<Grid>
<Border BorderThickness="1">
<AdornerDecorator>
<Grid x:Name="LayoutRoot">
<Grid.RowDefinitions>
<RowDefinition Height="25" />
<RowDefinition Height="*" />
<RowDefinition Height="15" />
</Grid.RowDefinitions>
<ContentPresenter Grid.Row="1" Grid.RowSpan="2" Margin="7"/>
<Rectangle x:Name="HeaderBackground" Height="25" Fill="{DynamicResource WindowBackgroundColorBrush}" VerticalAlignment="Top" Grid.Row="0"/>
<StackPanel Orientation="Horizontal" HorizontalAlignment="Right" VerticalAlignment="Top" WindowChrome.IsHitTestVisibleInChrome="True" Grid.Row="0">
<Button Command="{Binding Source={x:Static SystemCommands.MinimizeWindowCommand}}" ToolTip="minimize" Style="{StaticResource WindowButtonStyle}">
<Button.Content>
<Grid Width="30" Height="25" RenderTransform="1,0,0,1,0,1">
<Path Data="M0,6 L8,6 Z" Width="8" Height="7" VerticalAlignment="Center" HorizontalAlignment="Center"
Stroke="{Binding Foreground, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=Button}}" StrokeThickness="2" />
</Grid>
</Button.Content>
</Button>
<Grid Margin="1,0,1,0">
<Button x:Name="Restore" Command="{Binding Source={x:Static SystemCommands.RestoreWindowCommand}}" ToolTip="restore" Visibility="Collapsed" Style="{StaticResource WindowButtonStyle}">
<Button.Content>
<Grid Width="30" Height="25" UseLayoutRounding="True" RenderTransform="1,0,0,1,.5,.5">
<Path Data="M2,0 L8,0 L8,6 M0,3 L6,3 M0,2 L6,2 L6,8 L0,8 Z" Width="8" Height="8" VerticalAlignment="Center" HorizontalAlignment="Center"
Stroke="{Binding Foreground, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=Button}}" StrokeThickness="1" />
</Grid>
</Button.Content>
</Button>
<Button x:Name="Maximize" Command="{Binding Source={x:Static SystemCommands.MaximizeWindowCommand}}" ToolTip="maximize" Style="{StaticResource WindowButtonStyle}">
<Button.Content>
<Grid Width="31" Height="25">
<Path Data="M0,1 L9,1 L9,8 L0,8 Z" Width="9" Height="8" VerticalAlignment="Center" HorizontalAlignment="Center"
Stroke="{Binding Foreground, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=Button}}" StrokeThickness="2" />
</Grid>
</Button.Content>
</Button>
</Grid>
<Button Command="{Binding Source={x:Static SystemCommands.CloseWindowCommand}}" ToolTip="close" Style="{StaticResource WindowButtonStyle}">
<Button.Content>
<Grid Width="30" Height="25" RenderTransform="1,0,0,1,0,1">
<Path Data="M0,0 L8,7 M8,0 L0,7 Z" Width="8" Height="7" VerticalAlignment="Center" HorizontalAlignment="Center"
Stroke="{Binding Foreground, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=Button}}" StrokeThickness="1.5" />
</Grid>
</Button.Content>
</Button>
</StackPanel>
<TextBlock x:Name="WindowTitleTextBlock" Grid.Row="0" Text="{TemplateBinding Title}" HorizontalAlignment="Left" TextTrimming="CharacterEllipsis" VerticalAlignment="Center" Margin="8 -1 0 0" FontSize="16" Foreground="{TemplateBinding Foreground}"/>
<Grid Grid.Row="2">
<Path x:Name="ResizeGrip" Visibility="Collapsed" Width="12" Height="12" Margin="1" HorizontalAlignment="Right"
Stroke="{StaticResource BlueColorBrush}" StrokeThickness="1" Stretch="None" Data="F1 M1,10 L3,10 M5,10 L7,10 M9,10 L11,10 M2,9 L2,11 M6,9 L6,11 M10,9 L10,11 M5,6 L7,6 M9,6 L11,6 M6,5 L6,7 M10,5 L10,7 M9,2 L11,2 M10,1 L10,3" />
</Grid>
</Grid>
</AdornerDecorator>
</Border>
<Border BorderBrush="{StaticResource BlueColorBrush}" BorderThickness="1" Visibility="{Binding IsActive, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type Window}}, Converter={StaticResource bool2VisibilityConverter}}" />
</Grid>
</Border>
<ControlTemplate.Triggers>
<Trigger Property="WindowState" Value="Maximized">
<Setter TargetName="Maximize" Property="Visibility" Value="Collapsed" />
<Setter TargetName="Restore" Property="Visibility" Value="Visible" />
<Setter TargetName="LayoutRoot" Property="Margin" Value="7" />
</Trigger>
<Trigger Property="WindowState" Value="Normal">
<Setter TargetName="Maximize" Property="Visibility" Value="Visible" />
<Setter TargetName="Restore" Property="Visibility" Value="Collapsed" />
</Trigger>
<MultiTrigger>
<MultiTrigger.Conditions>
<Condition Property="ResizeMode" Value="CanResizeWithGrip" />
<Condition Property="WindowState" Value="Normal" />
</MultiTrigger.Conditions>
<Setter TargetName="ResizeGrip" Property="Visibility" Value="Visible" />
</MultiTrigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
<Setter Property="WindowChrome.WindowChrome">
<Setter.Value>
<WindowChrome CornerRadius="0" GlassFrameThickness="1" UseAeroCaptionButtons="False" />
</Setter.Value>
</Setter>
</Style>
回答by Joel
i would recommend Modern UI for WPF.
It has a very active maintainer it is awesome and free!
它有一个非常活跃的维护者,它很棒而且免费!


I'm currently porting some projects to MUI, first (and meanwhile second) impression is just wow!
我目前正在将一些项目移植到 MUI,第一(同时也是第二)印象就是哇!
To see MUI in action you could download XAML Spywhich is based on MUI.
要查看 MUI 的运行情况,您可以下载基于 MUI 的XAML Spy。
EDIT:Using Modern UI for WPF a few months and i'm loving it!
编辑:为 WPF 使用现代 UI 几个月,我很喜欢它!
回答by FlyingMaverick
Based on Viktor La Croix answerwith source above, I would change it to use the following:
根据Viktor La Croix对上述来源的回答,我将其更改为使用以下内容:


It's a better practice to use the Marlett font rather than Path Data points for the Minimize, Restore/Maximize and Close buttons.
对于最小化、恢复/最大化和关闭按钮,使用 Marlett 字体而不是路径数据点是更好的做法。
<StackPanel Orientation="Horizontal" HorizontalAlignment="Right" VerticalAlignment="Top" WindowChrome.IsHitTestVisibleInChrome="True" Grid.Row="0">
<Button Command="{Binding Source={x:Static SystemCommands.MinimizeWindowCommand}}" ToolTip="minimize" Style="{StaticResource WindowButtonStyle}">
<Button.Content>
<Grid Width="30" Height="25">
<TextBlock Text="0" FontFamily="Marlett" FontSize="14" VerticalAlignment="Center" HorizontalAlignment="Center" Padding="3.5,0,0,3" />
</Grid>
</Button.Content>
</Button>
<Grid Margin="1,0,1,0">
<Button x:Name="Restore" Command="{Binding Source={x:Static SystemCommands.RestoreWindowCommand}}" ToolTip="restore" Visibility="Collapsed" Style="{StaticResource WindowButtonStyle}">
<Button.Content>
<Grid Width="30" Height="25" UseLayoutRounding="True">
<TextBlock Text="2" FontFamily="Marlett" FontSize="14" VerticalAlignment="Center" HorizontalAlignment="Center" Padding="2,0,0,1" />
</Grid>
</Button.Content>
</Button>
<Button x:Name="Maximize" Command="{Binding Source={x:Static SystemCommands.MaximizeWindowCommand}}" ToolTip="maximize" Style="{StaticResource WindowButtonStyle}">
<Button.Content>
<Grid Width="31" Height="25">
<TextBlock Text="1" FontFamily="Marlett" FontSize="14" VerticalAlignment="Center" HorizontalAlignment="Center" Padding="2,0,0,1" />
</Grid>
</Button.Content>
</Button>
</Grid>
<Button Command="{Binding Source={x:Static SystemCommands.CloseWindowCommand}}" ToolTip="close" Style="{StaticResource WindowButtonStyle}">
<Button.Content>
<Grid Width="30" Height="25">
<TextBlock Text="r" FontFamily="Marlett" FontSize="14" VerticalAlignment="Center" HorizontalAlignment="Center" Padding="0,0,0,1" />
</Grid>
</Button.Content>
</Button>
回答by Joel
If you are willing to pay I strongly recommend you Telerik Components for WPF. They offer great styles/themesand there have specific themes for both, Office 2013 and Windows 8 (EDIT: and also a Visual Studio 2013 themed style). However there offering much more than just styles in fact you will get a whole bunch of controls which are really useful.
如果您愿意付费,我强烈建议您使用Telerik Components for WPF。它们提供了很棒的样式/主题,并且有针对 Office 2013 和 Windows 8 的特定主题(编辑:还有 Visual Studio 2013 主题样式)。然而,提供的不仅仅是样式,实际上您将获得一大堆非常有用的控件。
Here is how it looks in action (Screenshots taken from telerik samples):
这是它的实际效果(截取自 Telerik 样本的屏幕截图):




Here are the links to the telerik executive dashboard sample(first screenshot) and here for the CRM Dashboard(second screenshot).
以下是Telerik 执行仪表板示例(第一个屏幕截图)和CRM 仪表板(第二个屏幕截图)的链接。
They offer a 30 day trial, just give it a shot!
他们提供 30 天的试用期,试一试吧!
回答by Laila
Take a look at this WPF metro-styled window with optional glowing borders.
This is a stand-alone application using no other libraries than Microsoft.Windows.Shell (included) to create metro-styled windows with optional glowing borders.
这是一个独立的应用程序,除了 Microsoft.Windows.Shell(包括在内)之外,不使用其他库来创建带有可选发光边框的 Metro 风格窗口。
Supports Windows all the way back to XP (.NET4).
支持 Windows 一直到 XP (.NET4)。

