アプリケーション開発を行っていると、標準コントロールをベースに一部デザインの改変や機能追加を行いたい場合があります。
この記事では実際に標準コントロールを継承したカスタムコントロールを作成し解説します。
- 標準コントロールと同じプロパティや機能をそのまま継承・使用できる
- 標準コントロールから変更する機能分を記載するだけでよい
カスタムコントロールの作成
作成するカスタムコントロールについて
例として標準のTextBoxを継承したコントロールを作成し、見た目(スタイル)を変更します。(文字サイズ、フォント、色)
カスタムコントロールの見た目
カスタムコントロール使用時の記述(xaml)
<StackPanel Orientation="Horizontal">
<StackPanel Orientation="Vertical">
<TextBlock Text="標準TextBox" />
<TextBox
Width="200"
Margin="10"
Text="あいうえお" />
</StackPanel>
<StackPanel Orientation="Vertical">
<TextBlock Text="CutomTextBox" />
<ctrls:CustomTextBox
Width="200"
Margin="10"
Text="あいうえお" />
</StackPanel>
</StackPanel>
標準のTextBoxと同じように使用します。
TextBoxを継承しているため、各プロパティや公開関数はすべて標準TextBoxと同じものを使用可能です。もちろん独自プロパティ・機能の追加や既存機能の改変も可能です
カスタムコントロールのソースコード
プロジェクトの構成
今回、各ソースコードは以下の構成で配置します。
カスタムコントロールに関する定義(cs/xaml)はControlsフォルダにまとめて配置しています。
ソースコードと解説
CutomTextBox.xaml(カスタムTextBoxのスタイル)
<ResourceDictionary
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<!-- CustomTextBox用のStyleを定義(TextBoxを継承)-->
<Style
x:Key="CustomTextBoxStyle"
BasedOn="{StaticResource {x:Type TextBox}}"
TargetType="{x:Type TextBox}">
<!-- 見た目を変更 -->
<Setter Property="FontSize" Value="20" />
<Setter Property="FontFamily" Value="Comic Sans MS"/>
<Setter Property="Foreground" Value="Red"/>
<Setter Property="Background" Value="Yellow"/>
</Style>
</ResourceDictionary>
- x:Key=”CustomTextBoxStyle”
Styleに名前を付けています。あとでGeneric.xamlから呼び出すために必要です。 - BasedOn=”{StaticResource {x:Type TextBox}}”
この記述で標準TextBoxのスタイルを継承しています。デザインを独自に再定義する場合は不要です。(その場合はStyleタグ内部にControlTemplateの定義を記述する) - TargetType=”{x:Type TextBox}”
この段階ではTextBox向けのスタイルとして定義します。CustomTextBoxはTextBoxを継承するクラスとなるため。 - Styleタグの内部
BasedOnで継承したTextBoxから変更する点のみ記述します。(この例ではフォントや前景/背景色のみ。)記述していないプロパティ等は標準コントロールの値がそのまま使用されます。
カスタムコントロールのxamlファイルはVisualStudioのソリューションエクスプローラ上から追加⇒新しい項目からリソースディクショナリ(WPF)を追加します。
CustomTextBox.cs(カスタムTextBoxの実体)
using System;
using System.Collections.Generic;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
namespace AppProject.Controls
{
public class CustomTextBox : TextBox
{
static CustomTextBox()
{
DefaultStyleKeyProperty.OverrideMetadata(typeof(CustomTextBox), new FrameworkPropertyMetadata(typeof(CustomTextBox)));
}
/// <summary>
/// 基底処理上書きの例(フォーカス喪失時のイベント)
/// TextBoxの処理をoverrideして上書き、機能追加が可能。
/// </summary>
/// <param name="e"></param>
protected override void OnLostFocus(RoutedEventArgs e)
{
base.OnLostFocus(e);
// 何か処理を記載する ↓例えばメッセージボックスを表示
CustomTextBox customText = (CustomTextBox)e.OriginalSource;
MessageBox.Show(customText.Text);
}
}
}
- public class CustomTextBox : TextBox
カスタムコントロールのcsファイルを作成時はControlクラスを継承する記載となっていますが、継承元となる標準コントロール(TextBox)に書き換えます。
これによりTextBoxの各プロパティや関数をコールできるようになります。 - protected override void OnXXXXXX関数定義
標準コントロールのイベント処理を上書きすることが可能です。今回の例ではOnLostFocusを上書きしています。
カスタムコントロールのcsファイルはVisualStudioのソリューションエクスプローラ上から追加⇒新しい項目からカスタムコントロール(WPF)を追加します。
Generic.xaml
<ResourceDictionary
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:ctrls="clr-namespace:AppProject.Controls">
<!-- 各コントロールのStyle定義を参照 -->
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="/AppProject;component/Controls/Styles/CustomTextBox.xaml" />
</ResourceDictionary.MergedDictionaries>
<!-- 独自Styleをカスタムコントロールに適用 -->
<Style BasedOn="{StaticResource CustomTextBoxStyle}" TargetType="{x:Type ctrls:CustomTextBox}" />
</ResourceDictionary>
- <ResourceDictionary Source=”/AppProject;component/Controls/Styles/CustomTextBox.xaml” />
別途定義したCustomTextBoxのスタイルファイルを参照します。 - <Style BasedOn=”{StaticResource CustomTextBoxStyle}” TargetType=”{x:Type ctrls:CustomTextBox}” />
独自定義したCutomTextBoxStyleをCustomTextBoxに適用します。x:Key無しで記述することで、TargetTypeで指定したコントロールに適用されます。
自動生成された段階ではCustomTextBoxコントロールの暫定スタイル定義がGeneric.xaml上にありますが、CustomTextBox.xamlに定義を記載しなおしているため削除しています。
まとめ
今回は標準コントロールを継承してカスタムコントロールを作成する方法について記載しました。定義したカスタムコントロールは標準コントロールと同じく、xaml上に記載することで使用可能です。
カスタムコントロールを使用することでアプリケーション内でのデザインの統一ができ、変更時も一括で変更することが可能となります。基本的に標準コントロールは使わないようにした方が良いと思います。(何も変えなくともとりあえず標準を継承したカスタムコントロールを作成して使ったほうが良いんじゃないかなと。)
なお、TextBoxで説明しましたが、他の標準コントロールでも同じです。
勉強中の身ですので、誤りや不備等ありましたらご指摘いただけますと幸いです。