WPFの機能であるスタイル、テンプレートを使用してボタンとプログレスバーのUIをカスタマイズしてみました。メモとして記載を行います。
動作確認環境
- 動作環境:Windows Server 2003
- 開発環境:Visual Studio 2008 Professional
- .NET 3.5
1. 今回作成するボタンとプログレスバー
今回StyleとTemplateを使用して作成するプログラムの完成結果の画面イメージを掲載します。一番上がマウスがオーバーしたときのボタンで、真ん中が通常時のボタン。3番目がプログレスバーです。

今回は図のように赤い光沢のあるButtonとProgressbarを作成してみます。
2. カスタマイズボタンを作成する
Visual Studio を起動してソリューションを新規作成します。ソリューション名はWPFTemplateLibraryという名前で作成しました。
2.1 WPF クラスライブラリの作成
ソリューションエクスプローラを右クリックし、WPFGlassというWPFクラスライブラリを作成します。
作成後、プロジェクトを右クリックし、追加→リソースディディクショナリを選択し、CommonResource.xamlという名前でファイル名で作成します。
リソースファイルはボタンやプログレスバーの共通リソースを定義したものです。次のように編集します。
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<!-- テキスト -->
<SolidColorBrush x:Key="TextBrush" Color="White" />
<!-- バックグラウンドの定義 -->
<!-- 通常のバックグラウンド -->
<LinearGradientBrush x:Key="ControlBackground" StartPoint="0,0" EndPoint="0,1">
<GradientStop Offset="0" Color="#FFFF0000" />
<GradientStop Offset="0.5" Color="#FFFF0000" />
<GradientStop Offset="1" Color="#AADD4433" />
</LinearGradientBrush>
<!-- ボーダーカラー -->
<LinearGradientBrush x:Key="ControlBorder" StartPoint="0,0" EndPoint="0,1">
<GradientStop Offset="0" Color="#AAFF0000" />
<GradientStop Offset="0.8" Color="#AAFF0000" />
</LinearGradientBrush>
<!-- マウスオーバー時のバックグラウンド -->
<LinearGradientBrush x:Key="ControlBackgroundMouserOver" StartPoint="0,0" EndPoint="0,1">
<GradientStop Offset="0" Color="#FFFF0000" />
<GradientStop Offset="1" Color="#DDFF44FF" />
</LinearGradientBrush>
<LinearGradientBrush x:Key="ControlBackgroundMousePressed" StartPoint="0,0" EndPoint="0,1">
<GradientStop Offset="0" Color="#CCFFFFFF" />
<GradientStop Offset="0.1" Color="#CCFFFFFF" />
<GradientStop Offset="0.4" Color="#88FFFFFF" />
<GradientStop Offset="0.4" Color="#00FFFFFF" />
</LinearGradientBrush>
<!-- 光沢 -->
<LinearGradientBrush x:Key="ControlWhiteTop" StartPoint="0,0" EndPoint="0,1">
<GradientStop Offset="0" Color="#CCFFFFFF" />
<GradientStop Offset="0.1" Color="#CCFFFFFF" />
<GradientStop Offset="0.4" Color="#88FFFFFF" />
<GradientStop Offset="0.4" Color="#00FFFFFF" />
</LinearGradientBrush>
<RadialGradientBrush x:Key="ControlWhiteBottom"
GradientOrigin="0.5,1.0"
Center="0.5,1.0" RadiusX="0.7" RadiusY="0.1">
<RadialGradientBrush.GradientStops>
<GradientStop Color="#AAFFFFFF" Offset="0" />
<GradientStop Color="#00FFFFFF" Offset="1" />
</RadialGradientBrush.GradientStops>
</RadialGradientBrush>
</ResourceDictionary>
次に、赤いボタン用のリソースディクショナリを作成します。プロジェクトを右クリックし、追加→リソースディクショナリを選択肢、RedButton.xamlを作成します。
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="CommonResource.xaml" />
<ResourceDictionary Source="RedProgressBar.xaml" />
</ResourceDictionary.MergedDictionaries>
<Style x:Key="ForcusDefaultStyle" TargetType="{x:Type Control}" >
</Style>
<Style x:Key="RedButton" TargetType="{x:Type Button}">
<Setter Property="Margin" Value="1"></Setter>
<Setter Property="Padding" Value="14" />
<Setter Property="SnapsToDevicePixels" Value="false"></Setter>
<Setter Property="OverridesDefaultStyle" Value="true"></Setter>
<Setter Property="MinHeight" Value="20"></Setter>
<Setter Property="MinWidth" Value="16"></Setter>
<Setter Property="FontFamily" Value="Verdana"></Setter>
<Setter Property="FontSize" Value="11px"></Setter>
<Setter Property="Foreground" Value="{StaticResource TextBrush}"></Setter>
<Setter Property="FocusVisualStyle" Value="{StaticResource ForcusDefaultStyle}" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="Button">
<Grid x:Name="Content" RenderTransformOrigin="0.5,0.5">
<!-- ボーダー描画 -->
<Border Name="border" CornerRadius="9" Background="{StaticResource ControlBackground}"
BorderBrush="{StaticResource ControlBorder}" BorderThickness="1">
</Border>
<!-- background -->
<Rectangle x:Name="top" Margin="1,1,1,1" RadiusX="9" RadiusY="9" Fill="{StaticResource ControlWhiteTop}" >
</Rectangle>
<Rectangle x:Name="bottom" Margin="1,1,1,1" RadiusX="9" RadiusY="9" Fill="{StaticResource ControlWhiteBottom}" >
</Rectangle>
<ContentPresenter Margin="4" x:Name="innerContent" VerticalAlignment="Center" HorizontalAlignment="Center" />
</Grid>
<ControlTemplate.Triggers>
<Trigger Property="IsMouseOver" Value="true">
<Setter TargetName="border" Property="Background" Value="{StaticResource ControlBackgroundMouserOver}" />
</Trigger>
<Trigger Property="IsPressed" Value="true">
<Setter TargetName="top" Property="Fill" Value="{StaticResource ControlBackgroundMousePressed}" />
<Setter TargetName="innerContent" Property="RenderTransform">
<Setter.Value>
<TranslateTransform X="0" Y="1" />
</Setter.Value>
</Setter>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</ResourceDictionary>
次に、赤いプログレスバー用のリソースディクショナリを作成します。プロジェクトを右クリックし、追加→リソースディクショナリを選択、RedProgressBar.xamlというファイル名で作成し次のように編集します。
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="CommonResource.xaml" />
</ResourceDictionary.MergedDictionaries>
<LinearGradientBrush x:Key="ProgressBackground" StartPoint="0,0" EndPoint="0,1">
<GradientStop Offset="0" Color="#888888" />
<GradientStop Offset="1" Color="#AAAAAA" />
</LinearGradientBrush>
<Style TargetType="{x:Type ProgressBar}">
<Setter Property="MinHeight" Value="15" />
<Setter Property="MinWidth" Value="100" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type ProgressBar}">
<Grid>
<Border Name="PART_Track" CornerRadius="1" Background="{StaticResource ProgressBackground}" BorderThickness="1" BorderBrush="{StaticResource ControlBorder}"></Border>
<Grid Name="PART_Indicator" HorizontalAlignment="Left" >
<Rectangle x:Name="prgBackground" Margin="0" RadiusX="1" RadiusY="1" Fill="{StaticResource ControlBackground}" >
</Rectangle>
<Rectangle x:Name="Highlight1" Margin="1" RadiusX="1" RadiusY="1" Opacity="1" Fill="{StaticResource ControlWhiteTop}">
</Rectangle>
<Rectangle x:Name="Highlight2" Margin="0" RadiusX="1" RadiusY="1" Opacity="1" Fill="{StaticResource ControlWhiteBottom}">
</Rectangle>
</Grid>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</ResourceDictionary>
最後に、ユーザコントロール用のxamlを作成します。プロジェクトを右クリックし、追加ダイアログで、テンプレートにユーザコントロール(WPF)を選択し、UserControl1という名前で作成します。これでボタンと、プログレスバーに作成したスタイルが適用されるようになります。
<UserControl x:Class="WPFGlass.UserControl1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
>
<UserControl.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="RedButton.xaml" />
<ResourceDictionary Source="RedProgressBar.xaml" />
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
</UserControl.Resources>
<StackPanel>
<Button Style="{StaticResource RedButton}" x:Name="btnSample1" Content="ClickMe!!"/>
<Button Style="{StaticResource RedButton}" x:Name="btnSample2" Content="MouseOver"/>
<ProgressBar x:Name="prgBar" Value="40" />
</StackPanel>
</UserControl>
2.2 WPFアプリケーションを作成
2.1で作成したユーザコントロールを表示するプログラムを作成します。ソリューションを右クリックし、WPFアプリケーションプロジェクトを新規作成します。プロジェクト名は WpfApplication1 としました。
プロジェクト作成後、2.1のWPFクラスライブラリを参照に加えて、既定で作成されるWindows1.xamlを次のように編集して、完了です。
<Window x:Class="WpfApplication1.Window1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:custom="clr-namespace:WPFGlass;assembly=WPFGlass"
Title="Window1" >
<Grid>
<custom:UserControl1 x:Name="userControl" />
</Grid>
</Window>
3. まとめ
WPFは今までのものと比べれば簡単にカスタマイズされたUIを簡単に作成できます。ただ、懲りすぎないように注意したほうがよさそうです。
http://softgarden.blog.ocn.ne.jp/blog/2011/07/ironpythonredgl.html
で、参考にさせて頂きました。