WPF

【WPF】標準コントロールを継承したカスタムコントロールを作る

アプリケーション開発を行っていると、標準コントロールをベースに一部デザインの改変や機能追加を行いたい場合があります。

この記事では実際に標準コントロールを継承したカスタムコントロールを作成し解説します。

標準コントロールの継承によるメリット
  • 標準コントロールと同じプロパティや機能をそのまま継承・使用できる
  • 標準コントロールから変更する機能分を記載するだけでよい

カスタムコントロールの作成

作成するカスタムコントロールについて

例として標準の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で説明しましたが、他の標準コントロールでも同じです。
勉強中の身ですので、誤りや不備等ありましたらご指摘いただけますと幸いです。

 

COMMENT

メールアドレスが公開されることはありません。

CAPTCHA