WPFプログラミング備忘録

WPF Behaviorを使ってコントロールの機能を強化しよう

WPF

はじめに

この記事ではBehaviorを使ってコントロールの機能を強化できることを確認します。

サンプルとしてテキストボックスコントロールの背景色を以下のとおり装飾することにします。

  • フォーカスが当たったときは黄色にする
  • フォーカスが外れたときは灰色にする

今回の開発環境は以下のとおりです。

オペレーティングシステムWindows10 x64
Visual StudioMicrosoft Visual Studio Community 2019 Version 16.11.2
.NET Framewrok4.7.2

Microsoft.Xaml.Behaviorsのインストール

以下の手順でMicrosoft.Xaml.Behaviorsをプロジェクトにインストールします。

  1. メニューから「ツール」->「NuGet パッケージ マネージャー」->「ソリューションの NuGet パッケージの管理」を選択する
  2. 「参照」を選択しMicrosoft.Xaml.Behaviorsで検索する
  3. 左側の一覧からMicrosoft.Xaml.Behaviors.Wpfを選択する
  4. 右側のプロジェクトの一覧からインストール先のプロジェクトを選択する
  5. 「インストール」ボタンを押す

参照設定にMicrosoft.Xaml.Behaviorsが追加されます。

Behaviorを拡張したクラスの作成

クラスを作成します。「プロジェクトを右クリック」->「追加」->「クラス」でクラスを追加します。

今回はChangeTextBoxColorという名前にします。

ChangeTextBoxColor.csファイルに以下のusing宣言を追加します。

using System.Windows.Controls;
using System.Windows.Media;
using Microsoft.Xaml.Behaviors;

ChangeTextBoxColorクラスをpublicクラスとした後、基底クラスにBehavior<TextBox>を指定します。

OnAttachedメソッドとOnDetachingメソッドをオーバーライドします。

overrideと入力してスペースキーを押すとメソッドの一覧が表示されるので上記2つのメソッドを追加してください。

フォーカスが当たったときと外れたときの背景色のために2つのSolidColorBrush型のpublicプロパティを追加します。

全ての実装を終えたChangeTextBoxColorクラスは以下のとおりです。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Controls;
using System.Windows.Media;
using Microsoft.Xaml.Behaviors;

namespace WpfBehaviorSample
{
    public class ChangeTextBoxColor : Behavior<TextBox>
    {
        public SolidColorBrush BackBrushOnGotFocus { get; set; }
        public SolidColorBrush BackBrushOnLostFocus { get; set; }
        
        protected override void OnAttached()
        {
            base.OnAttached();

            AssociatedObject.GotFocus += AssociatedObject_GotFocus;

            AssociatedObject.LostFocus += AssociatedObject_LostFocus;
        }

        private void AssociatedObject_LostFocus(object sender, System.Windows.RoutedEventArgs e)
        {
            AssociatedObject.Background = BackBrushOnLostFocus;
        }

        private void AssociatedObject_GotFocus(object sender, System.Windows.RoutedEventArgs e)
        {
            AssociatedObject.Background = BackBrushOnGotFocus;
        }

        protected override void OnDetaching()
        {
            base.OnDetaching();

            AssociatedObject.GotFocus -= AssociatedObject_GotFocus;

            AssociatedObject.LostFocus -= AssociatedObject_LostFocus;
        }
    }
}

Behaviorで拡張したテキストボックスコントロールの配置

MainWindow.xamlを開きます。Behaviorsを使用可能にするためにWindow要素に以下の属性を追記してください。

xmlns:bhv="http://schemas.microsoft.com/xaml/behaviors"

Gridを削除してStackPanelを追加し3つのTextBoxコントロールを配置します。

全ての実装を終えたMainWindow.xamlは以下のとおりです。

<Window x:Class="WpfBehaviorSample.MainWindow"
        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:WpfBehaviorSample"
        xmlns:bhv="http://schemas.microsoft.com/xaml/behaviors"
        mc:Ignorable="d"
        Title="MainWindow" Height="250" Width="400">
 
    <StackPanel VerticalAlignment="Center" FocusManager.FocusedElement="{Binding ElementName=tb01}">
 
        <TextBox x:Name="tb01" Width="240" Height="30" Margin="10" Background="LightGray">
            <bhv:Interaction.Behaviors>
                <local:ChangeTextBoxColor BackBrushOnGotFocus="LightYellow"
                                          BackBrushOnLostFocus="LightGray"/>
            </bhv:Interaction.Behaviors>
        </TextBox>

        <TextBox Width="240" Height="30" Margin="10" Background="LightGray">
            <bhv:Interaction.Behaviors>
                <local:ChangeTextBoxColor BackBrushOnGotFocus="LightYellow"
                                          BackBrushOnLostFocus="LightGray"/>
            </bhv:Interaction.Behaviors>
        </TextBox>

        <TextBox Width="240" Height="30" Margin="10" Background="LightGray">
            <bhv:Interaction.Behaviors>
                <local:ChangeTextBoxColor BackBrushOnGotFocus="LightYellow"
                                          BackBrushOnLostFocus="LightGray"/>
            </bhv:Interaction.Behaviors>
        </TextBox>
    
    </StackPanel>

</Window>

プログラム起動時に一番上のTextBoxコントロールにフォーカスを当てるためFocusManagerを使用しています。

ビルドして実行すると以下のウィンドウが表示されます。

一番上のTextBoxコントロールにフォーカスが当たっているので背景色が黄色になっています。

上から二番目のTextBoxコントロールにフォーカスを当てると下図のとおり背景色が黄色になります。

一番下のTextBoxコントロールも同様です。

今回はBehaviorを使ってコントロールの機能を強化しました。Behaviorは上手く使えば煩わしいコードビハインドを減らすことができます。

以上です。

コメント