Skip to content

Instantly share code, notes, and snippets.

@Nia-TN1012
Last active March 25, 2016 06:11
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save Nia-TN1012/37f4ed0f6e809a052125 to your computer and use it in GitHub Desktop.
Save Nia-TN1012/37f4ed0f6e809a052125 to your computer and use it in GitHub Desktop.
クラッシックテーマ風のウィンドウです。(For Qiita : [C# / WPF] WPFでWindow 9xのクラッシックテーマを再現してみよう)

このGistはQiitaの記事「[C# / WPF] WPFでWindow 9xのクラッシックテーマを再現してみよう」( http://qiita.com/nia_tn1012/items/dad2ad412d648401600f )で扱っているプログラムです。

◆ ファイルの内容

  • CaptionButtonConverter.cs :

  • MainWindowConverter.cs   :

  • App.xaml          :

  • MainWindow.xaml      : メインウィンドウ

  • MainWindow.xaml.cs     : メインウィンドウ(分離コード)

  • Readme.md : このファイル

<Application x:Class="ClassicStyle.App"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:ClassicStyle"
StartupUri="MainWindow.xaml">
<Application.Resources>
<ResourceDictionary Source="/PresentationFramework.Classic, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35;component/themes/classic.xaml"/>
</Application.Resources>
</Application>
using System;
using System.Windows;
using System.Windows.Data;
using System.Globalization;
namespace ClassicStyle {
/// <summary>
/// 最大化キャプションボタンの表示文字列です。
/// </summary>
public sealed class MaximizeCaptionButtonContentConverter : IValueConverter {
public object Convert( object value, Type targetType, object parameter, CultureInfo culture ) =>
// Malettフォントでは「1」が「最大化」、「2」が「元に戻す」です。
value is WindowState && ( WindowState )value == WindowState.Maximized ? "2" : "1";
public object ConvertBack( object value, Type targetType, object parameter, CultureInfo culture ) => null;
}
/// <summary>
/// 最大化キャプションボタンのツールチップです。
/// </summary>
public sealed class MaximizeCaptionButtonTooltipConverter : IValueConverter {
public object Convert( object value, Type targetType, object parameter, CultureInfo culture ) =>
value is WindowState && ( WindowState )value == WindowState.Maximized ? "元に戻す" : "最大化";
public object ConvertBack( object value, Type targetType, object parameter, CultureInfo culture ) => null;
}
/// <summary>
/// ウィンドウのリサイズモードに応じて最大化キャプションボタンの有効・無効を設定します。
/// </summary>
public sealed class MaximizeCaptionButtonEnableConverter : IValueConverter {
public object Convert( object value, Type targetType, object parameter, CultureInfo culture ) =>
value is ResizeMode && ( ResizeMode )value != ResizeMode.CanMinimize;
public object ConvertBack( object value, Type targetType, object parameter, CultureInfo culture ) => null;
}
/// <summary>
/// ウィンドウのリサイズモードに応じて最大化・最小化キャプションボタンの表示・非表示を設定します。
/// </summary>
public sealed class ResizeCaptionButtonVisibilityConverter : IValueConverter {
public object Convert( object value, Type targetType, object parameter, CultureInfo culture ) =>
value is ResizeMode && ( ResizeMode )value != ResizeMode.NoResize ? Visibility.Visible : Visibility.Collapsed;
public object ConvertBack( object value, Type targetType, object parameter, CultureInfo culture ) => null;
}
}
<Window x:Class="ClassicStyle.MainWindow"
x:Name="MainWindow1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:ClassicStyle"
mc:Ignorable="d"
ResizeMode="CanResizeWithGrip"
Title="MainWindow" Height="350" Width="525"
Icon="small.ico">
<Window.Resources>
<!-- Window用カラー -->
<SolidColorBrush x:Key="ClassicMainBackgroundKey" Color="#FFF0F0F0"/>
<SolidColorBrush x:Key="ClassicMainForegroundKey" Color="Black"/>
<SolidColorBrush x:Key="ClassicMainBorderBrushKey" Color="#FFF0F0F0"/>
<!-- Converter -->
<local:BorderThicknessByWindowStateConverter x:Key="BorderThicknessByWindowStateConverterKey"/>
<local:BackgroundBorderConverter x:Key="BackgroundBorderConverterKey"/>
<local:CaptionBarBackgroundConverter x:Key="CaptionBarBackgroundConverterKey"/>
<local:MaximizeCaptionButtonContentConverter x:Key="MaximizeCaptionButtonContentConverterKey"/>
<local:MaximizeCaptionButtonTooltipConverter x:Key="MaximizeCaptionButtonTooltipConverter"/>
<local:MaximizeCaptionButtonEnableConverter x:Key="MaximizeCaptionButtonEnableConverterKey"/>
<local:ResizeCaptionButtonVisibilityConverter x:Key="ResizeCaptionButtonVisibilityConverter"/>
</Window.Resources>
<WindowChrome.WindowChrome>
<WindowChrome CaptionHeight="{x:Static SystemParameters.CaptionHeight}"
ResizeBorderThickness="{x:Static SystemParameters.WindowResizeBorderThickness}"
GlassFrameThickness="0,0,0,1"/>
</WindowChrome.WindowChrome>
<Window.CommandBindings>
<CommandBinding Command="{x:Static SystemCommands.CloseWindowCommand}"
Executed="CloseWindow"/>
<CommandBinding Command="{x:Static SystemCommands.MaximizeWindowCommand}"
Executed="MaximizeOrRestoreWindow"/>
<CommandBinding Command="{x:Static SystemCommands.MinimizeWindowCommand}"
Executed="MinimizeWindow"/>
</Window.CommandBindings>
<Border BorderBrush="{StaticResource ClassicMainBorderBrushKey}"
BorderThickness="{Binding WindowState,
Converter={StaticResource BorderThicknessByWindowStateConverterKey},
ElementName=MainWindow1}"
Background="{StaticResource ClassicMainBackgroundKey}">
<Grid>
<!-- 上からタイトルバー、コンテンツ -->
<Grid.RowDefinitions>
<RowDefinition Height="{x:Static SystemParameters.CaptionHeight}"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<!-- タイトルバー -->
<Grid Grid.Row="0"
Background="{Binding IsActive,
Converter={StaticResource CaptionBarBackgroundConverterKey},
ElementName=MainWindow1}">
<!-- 左からアイコン、タイトル、コマンドボタン -->
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="Auto"/>
</Grid.ColumnDefinitions>
<Image Grid.Column="0"
Margin="3"
Source="{Binding Icon, ElementName=MainWindow1}"/>
<!-- ウィンドウタイトルを表示します。 -->
<Grid Grid.Column="1">
<StackPanel HorizontalAlignment="Left"
VerticalAlignment="Center">
<TextBlock Text="{Binding Title, ElementName=MainWindow1}"
Foreground="White"
Padding="5,0"/>
</StackPanel>
</Grid>
<!-- 最小化、最大化、閉じるボタンを設置します。 -->
<Grid Grid.Column="2">
<StackPanel Orientation="Horizontal"
Margin="0,0,2,0"
HorizontalAlignment="Right"
VerticalAlignment="Center"
TextBlock.FontFamily="Marlett">
<Button Content="0"
Focusable="False"
WindowChrome.IsHitTestVisibleInChrome="True"
Visibility="{Binding ResizeMode, Converter={StaticResource ResizeCaptionButtonVisibilityConverter}, ElementName=MainWindow1}"
ToolTip="最小化"
Command="{x:Static SystemCommands.MinimizeWindowCommand}" />
<Button Content="{Binding WindowState,Converter={StaticResource MaximizeCaptionButtonContentConverterKey}, ElementName=MainWindow1}"
Focusable="False"
WindowChrome.IsHitTestVisibleInChrome="True"
IsEnabled="{Binding ResizeMode, Converter={StaticResource MaximizeCaptionButtonEnableConverterKey}, ElementName=MainWindow1}"
Visibility="{Binding ResizeMode, Converter={StaticResource ResizeCaptionButtonVisibilityConverter}, ElementName=MainWindow1}"
ToolTip="{Binding WindowState, Converter={StaticResource MaximizeCaptionButtonTooltipConverter}, ElementName=MainWindow1}"
Command="{x:Static SystemCommands.MaximizeWindowCommand}"/>
<Button Content="r"
Focusable="False"
WindowChrome.IsHitTestVisibleInChrome="True"
Margin="2,0,0,0"
ToolTip="閉じる"
Command="{x:Static SystemCommands.CloseWindowCommand}"/>
</StackPanel>
</Grid>
</Grid>
<!-- コンテンツ -->
<Grid Grid.Row="1">
<Button Content="Button1"
Margin="10"
Width="120" Height="30"
HorizontalAlignment="Center"
VerticalAlignment="Center"
Click="Button_Click"/>
</Grid>
</Grid>
</Border>
</Window>
using System.Windows;
using System.Windows.Input;
namespace ClassicStyle {
/// <summary>
/// MainWindow.xaml の相互作用ロジック
/// </summary>
public partial class MainWindow : Window {
public MainWindow() {
InitializeComponent();
}
#region キャプションボタンのイベント
/// <summary>
/// 閉じる及び、終了ボタンを押した時のイベントです。
/// </summary>
private void CloseWindow( object sender, ExecutedRoutedEventArgs e ) {
// アプリを終了します。
Close();
}
/// <summary>
/// 最小化ボタンを押した時のイベントです。
/// </summary>
private void MinimizeWindow( object sender, ExecutedRoutedEventArgs e ) {
// ウインドウを最小化します。
WindowState = WindowState.Minimized;
}
/// <summary>
/// 最大化ボタンを押した時のイベントです。
/// </summary>
private void MaximizeOrRestoreWindow( object sender, ExecutedRoutedEventArgs e ) {
// ウィンドウを最大化( もしくは元のサイズに )します。
WindowState = WindowState != WindowState.Maximized ? WindowState.Maximized : WindowState.Normal;
}
#endregion
private void Button_Click( object sender, RoutedEventArgs e ) {
MessageBox.Show( "Hello World!" );
}
}
}
using System;
using System.Windows;
using System.Windows.Media;
using System.Windows.Data;
using System.Globalization;
namespace ClassicStyle {
/// <summary>
/// ウィンドウのアクティブ状態に合わせて、Windows直下のBorderのBorderBrush値を調節します。
/// </summary>
public sealed class BackgroundBorderConverter : IValueConverter {
public object Convert( object value, Type targetType, object parameter, CultureInfo culture ) =>
( value is bool && ( bool )value ) ? parameter as SolidColorBrush : Brushes.LightGray;
public object ConvertBack( object value, Type targetType, object parameter, CultureInfo culture ) => null;
}
/// <summary>
/// ウィンドウのアクティブ状態に合わせて、タイトルバー部分Background値を調節します。
/// </summary>
public sealed class CaptionBarBackgroundConverter : IValueConverter {
// Windows 95のタイトルバーの色
//static SolidColorBrush Active = new SolidColorBrush( Color.FromRgb( 0, 0x02, 0x81 ) );
//static SolidColorBrush InActive = new SolidColorBrush( Color.FromRgb( 0x80, 0x80, 0x80 ) );
// Windows 98のタイトルバーの色
//static LinearGradientBrush Active = new LinearGradientBrush( Color.FromRgb( 0, 0x02, 0x81 ), Color.FromRgb( 0x10, 0x84, 0xD0 ), new Point( 0, 0.5 ), new Point( 0.5, 1 ) );
//static LinearGradientBrush InActive = new LinearGradientBrush( Color.FromRgb( 0x80, 0x80, 0x80 ), Color.FromRgb( 0xB3, 0xB3, 0xB3 ), new Point( 0, 0.5 ), new Point( 0.5, 1 ) );
// Windows Meやクラッシックスタイルのタイトルバーの色
static LinearGradientBrush Active = new LinearGradientBrush( Color.FromRgb( 0x0B, 0x25, 0x6B ), Color.FromRgb( 0xA6, 0xCA, 0xF0 ), new Point( 0, 0.5 ), new Point( 0.5, 1 ) );
static LinearGradientBrush InActive = new LinearGradientBrush( Color.FromRgb( 0x80, 0x80, 0x80 ), Color.FromRgb( 0xB6, 0xB6, 0xB6 ), new Point( 0, 0.5 ), new Point( 0.5, 1 ) );
public object Convert( object value, Type targetType, object parameter, CultureInfo culture ) =>
value is bool && ( bool )value ? Active : InActive;
public object ConvertBack( object value, Type targetType, object parameter, CultureInfo culture ) => null;
}
/// <summary>
/// ウィンドウの最大化によって Border.Thickness を調節します。
/// </summary>
public sealed class BorderThicknessByWindowStateConverter : IValueConverter {
public object Convert( object value, Type targetType, object parameter, CultureInfo culture ) =>
value is WindowState && ( WindowState )value == WindowState.Maximized ? 8.0 : 2.0;
public object ConvertBack( object value, Type targetType, object parameter, CultureInfo culture ) => null;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment