首页 文章

即使在Windows 7中,使WPF应用程序看起来也是Metro风格的? (Window Chrome /主题/主题)

提问于
浏览
116

我喜欢新的Office套件和Visual Studio上的窗口镶边:

enter image description here

我当然还在为Windows 7开发应用程序,但我想知道是否有一种快速简便的方法(阅读:WPF样式或Windows库)来模仿这种风格 . 我过去做过一些窗口镀铬样式,但让它看起来和行为恰到好处是非常棘手的 .

有没有人知道是否有现有的模板或库来为我的WPF应用程序添加“现代UI”外观?

5 回答

  • 44

    我所做的是创建自己的窗口和样式 . 因为我喜欢控制一切,我不想让一些外部库只使用它的窗口 . 我看着已经提到MahApps.Metro on GitHub

    MahApps

    而且非常好Modern UI on CodePlex . (仅限.NET4.5)

    Modern UI

    还有一个是Elysium但我真的没有试过这个 .

    Elysium

    当我看到自己做的主要原因时,我所做的风格非常简单 . 我也为你做了一个:)我应该说,如果没有探索 Modern UI 我就无法做到这一点,这是非常有帮助的 . 我试着让它看起来像VS2012 Window . 看起来像这样 .

    MyWindow

    这是代码(请注意它的目标是.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);
        }
    }
    

    这里资源:

    <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>
    
  • 15

    我最终选择的解决方案是MahApps.Metrogithub),它(现在在两个软件上使用它之后)我认为是一个优秀的UI工具包(建议信用Oliver Vogel) .

    Window style

    它只需要很少的工作就能完成应用程序,并且可以对标准的Windows 8控件进行调整 . 它非常强大 .

    Text box watermark

    Nuget上有一个版本:

    您可以使用GUI通过Nuget安装MahApps.Metro(右键单击您的项目,管理Nuget参考,搜索'MahApps.Metro')或通过控制台:PM> Install-Package MahApps.Metro

    它也是 free - 即使是商业用途 .

    更新10-29-2013:

    我发现MaApps.Metro的Github版本包含了当前nuget版本中没有的控件和样式,包括:

    数据网格:

    enter image description here

    清洁窗口:

    enter image description here

    弹出:

    enter image description here

    瓷砖:

    enter image description here

    github存储库非常活跃,有很多用户贡献 . 我建议检查一下 .

  • 3

    我会推荐Modern UI for WPF .

    它有一个非常活跃的维护者,它是真棒和免费的!

    Modern UI for WPF (Screenshot of the sample application

    我目前正在将一些项目移植到MUI,首先(同时第二)印象就是哇!

    要查看MUI的运行情况,您可以下载基于MUI的XAML Spy .

    EDIT: 使用WPF的现代UI几个月,我很喜欢它!

  • 39

    根据Viktor La Croix answer上面的源代码,我会将其更改为使用以下内容:

    Marlett Font Example

    对于最小化,恢复/最大化和关闭按钮,使用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>
    
  • 144

    如果你愿意支付我强烈推荐你Telerik Components for WPF . 它们提供了很好的styles/themes,并且Office 2013和Windows 8都有特定的主题(编辑:以及Visual Studio 2013主题风格) . 然而,实际上你提供的不仅仅是样式,你会得到一大堆非常有用的控件 .

    以下是它的实际效果(取自telerik样本的截图):

    Telerik Dashboard Sample

    Telerik CRM Dashboard Sample

    以下是telerik executive dashboard sample(第一个屏幕截图)和CRM Dashboard(第二个屏幕截图)的链接 .

    他们提供30天的试用期,只需试一试!

相关问题