Windows 7でも、WPFアプリケーションをMetroスタイルのように見せますか?(ウィンドウクローム/テーマ/テーマ)


123

新しいOfficeスイートとVisual Studioのウィンドウクロームが好きです。

ここに画像の説明を入力してください

もちろん、まだWindows 7用のアプリケーションを開発していますが、このスタイルをエミュレートするための迅速で簡単な方法(WPFスタイルまたはWindowsライブラリ)があるかどうか疑問に思っています。私は過去にウィンドウクロームのスタイリングを行ったことがありますが、見た目や動作を正しくすることは非常に難しいです。

WPFアプリケーションに「モダンUI」のルックアンドフィールを追加するための既存のテンプレートまたはライブラリがあるかどうか誰かが知っていますか?


8
このガイド/ NuGetパッケージは役に立つかもしれません:MahaApps Metroこれには、Metro Look&FeelでWPFアプリを作成するためのスタイルとコントロールのセットが含まれています。
Oliver Vogel

書籍、ツール、ソフトウェアライブラリ、チュートリアル、またはその他のオフサイトリソースを推奨または検索するように求める質問は、意見や回答を集める傾向があるため、Stack Overflowのトピックから外れています。代わりに、問題と、それを解決するためにこれまでに行われたことを説明してください。
スコットソルマー2014

回答:


149

私がしたことは、自分のウィンドウとスタイルを作成することでした。私はすべてを制御したいので、そこからウィンドウを使用するだけの外部ライブラリが欲しくなかったからです。私はGitHubですでに述べたMahApps.Metroを見ました

MahApps

また、GitHubの非常に優れたモダンUI。(.NET4.5のみ)

モダンUI

もう1つはElysiumですが、私は実際にこれを試しませんでした。

エリジウム

私がやったスタイルは、これらでどのように行われているかを見て、本当に簡単でした。今、私は自分のウィンドウを持っており、xamlで好きなことができます...私にとっては、私が自分でウィンドウを作成した主な理由です。そして、私もあなたのためにもう1つ作成しました:)おそらく私は、モダンUIを探索せずにそれを行うことはできないと言えるでしょう。VS2012ウィンドウのように見せてみました。こんな感じです。

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>

1
こんにちは、あなたが投稿したこの素晴らしいコードを本当にありがとう。お願いです、窓に影をつけることは可能ですか?私が考え出した唯一のものは、に変更するGlassFrameThicknessこと1です。しかし、影は強すぎて暗すぎます。ウェイトと不透明度を変更するにはどうすればよいですか?
xperator 2013年


MahAppsを使用する代わりに、コンポーネントの独自のカスタマイズを作成することは非常に難しいですか?
Matheus Saraiva 2016

ファンタスティコ!このすばらしい貢献に本当に感謝します。私は何度も同じことをやろうとしましたが、そのような完璧な結果は得られませんでした。
Leodev

上の青色の境界線の太さを増やし、他のすべての側面の境界線を削除したい場合(回答のelysium picなど)、何を変更する必要がありますか?私はwpfに
慣れ

49

私が最終的に選択したソリューションはMahApps.Metrogithubでした(これを2つのソフトウェアで使用した後)優れたUIキット(提案のためのOliver Vogelの功績)を検討します。

ウィンドウスタイル

ほんの少しの労力でアプリケーションのスキンを作成し、標準のWindows 8コントロールを適応させます。非常に堅牢です。

テキストボックスの透かし

Nugetでバージョンを入手できます。

GUIを使用してNuget経由でMahApps.Metroをインストールできます(プロジェクトを右クリックして、Nuget参照を管理し、 'MahApps.Metro'を検索します)またはコンソールを使用します。

PM>インストールパッケージMahApps.Metro

商用利用も無料です。

2013年10月29日更新:

MahApps.MetroのGithubバージョンには、現在のnugetバージョンでは使用できないコントロールとスタイルが含まれていることがわかりました。

データグリッド:

ここに画像の説明を入力してください

きれいなウィンドウ:

ここに画像の説明を入力してください

フライアウト:

ここに画像の説明を入力してください

タイル:

ここに画像の説明を入力してください

githubリポジトリは非常にアクティブで、かなりのユーザーの貢献があります。ぜひチェックしてみてください。


私はそれをテストしています、素晴らしい+1 :)
Akrem

3
とてもいいアップデート!私はまた、MahApps.Metro、WPFとElysiumのモダンUIを試してみました。ElysiumはWebサイト/ドキュメントで使用と混乱が非常に複雑であることがわかりました。モダンUIとMahApps.Metroは軽量で使いやすいですが、MahAppsです。 MetroはWPFフォームコントロールでより競争力があります。
Cheung

MahAppsを使用する代わりに、コンポーネントの独自のカスタマイズを作成することは非常に難しいですか?
Matheus Saraiva 2016

42

Modern UI for WPFをお勧めします。

非常にアクティブなメンテナーがいて、それは素晴らしく、無料です!

WPFの最新のUI(サンプルアプリケーションのスクリーンショット)

現在、いくつかのプロジェクトをMUIに移植していますが、最初の(そして2番目の)印象はすごいです!

MUIの動作を確認するには、MUIに基づくXAML Spyをダウンロードします。

編集: WPF for Modern UIを数ヶ月使用して、私はそれを愛しています!


16

上記のソースを使用したViktor La Croixの回答に基づいて、次のように変更します。

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>


こんにちはFlying maverickです。マーレットフォントを使用する方が良い理由を説明できますか?3つの異なる実装があり、どれを使用するかわかりません。1つ目はパスデータポイントを使用し、2つ目はマーレットを使用し、3つ目はボタンをSVG形式で再現したものです。私はこのプロジェクトで100%のベストプラクティスを使用しようとしていますが、どれが最良のオプションであるかわかりません。なぜマーレットが優れているのか説明してくれませんか?
user1632018 2014年

1
こんにちはuser1632018 WinformまたはWPFでカスタムクロムウィンドウを作成する場合は、システムで使用できる「Marlett」フォントを確認してください。このフォントには、Windowsで最小化、最大化、復元、閉じるボタンに使用される実際のグリフが含まれています。このフォントを使用すると、通常使用されるカスタム画像の代わりに、カスタムクロムウィンドウでこれらのグリフを簡単に再利用できます。:あなたは、Windowsの文字地図や詳細については、以下のリンクでMarlettフォントを見てとることができmicrosoft.com/typography/fonts/font.aspx?FMID=1264 この情報がお役に立てば幸いです。
FlyingMaverick 2014年

2

お支払いを希望される場合は、Telerik Components for WPFをお勧めします。彼らは素晴らしいスタイル/テーマを提供し、Office 2013とWindows 8の両方に特定のテーマがあります(編集:Visual Studio 2013をテーマにしたスタイル)。ただし、実際にはスタイルだけでなく、他にも多くの機能があり、非常に便利なコントロールがたくさん集まっています。

実際の動作は次のとおりです(telerikサンプルから取得したスクリーンショット)。

Telerikダッシュボードのサンプル

Telerik CRMダッシュボードサンプル

これは、telerikエグゼクティブダッシュボードのサンプル(最初のスクリーンショット)とCRMダッシュボード(2番目のスクリーンショット)へのリンクです。

彼らは30日間のトライアルを提供しています、それを試してください!


弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.