2012年4月28日土曜日

wpf : 添付ビヘイビアでTextBoxにフォーカスが移った時全選択にするプロパティを作成

タイトルどおりのものを作りました。 リソースのスタイルに書いておけばいっぺんに適用できます。 アプリケーション全体で使うリソースディクショナリとかを用意しておけば楽。

// TextBoxGotFocusBehaviors.cs
using System;
using System.Diagnostics;
using System.Windows;
using System.Windows.Controls;

namespace UserControls
{
    public class TextBoxGotFocusBehaviors
    {
        public static readonly DependencyProperty SelectAllOnGotFocusProperty =
                DependencyProperty.RegisterAttached(
                        "SelectAllOnGotFocus",
                        typeof(bool),
                        typeof(TextBoxGotFocusBehaviors),
                        new UIPropertyMetadata(false, SelectAllOnGotFocusChanged)
                );

        [AttachedPropertyBrowsableForType(typeof(TextBox))]
        public static bool GetSelectAllOnGotFocus(DependencyObject obj)
        {
            return (bool)obj.GetValue(SelectAllOnGotFocusProperty);
        }

        [AttachedPropertyBrowsableForType(typeof(TextBox))]
        public static void SetSelectAllOnGotFocus(DependencyObject obj, bool value)
        {
            obj.SetValue(SelectAllOnGotFocusProperty, value);
        }

        private static void SelectAllOnGotFocusChanged(DependencyObject sender, DependencyPropertyChangedEventArgs evt)
        {
            TextBox textBox = sender as TextBox;
            if (textBox == null)
                return;

            textBox.GotFocus -= OnTextBoxGotFocus;
            if((bool)evt.NewValue)
                textBox.GotFocus += OnTextBoxGotFocus;
        }

        private static void OnTextBoxGotFocus(object sender, RoutedEventArgs e)
        {
            TextBox textBox = sender as TextBox;
            Debug.Assert(textBox != null);

            textBox.Dispatcher.BeginInvoke((Action)(() => textBox.SelectAll()));
        }
    }
}

どうでもいいけど、ほぼ定型文で出来てるなぁ。

使う側の例は、

<Window x:Class="TextBoxGotFocusBehaviorsTest.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:appCtrls="clr-namespace:UserControls"
        Title="MainWindow" SizeToContent="WidthAndHeight" Width="200">
    <StackPanel>
        <StackPanel>
            <StackPanel.Resources>
                <Style TargetType="TextBox">
                    <Setter Property="appCtrls:TextBoxGotFocusBehaviors.SelectAllOnGotFocus" Value="True" />
                </Style>
            </StackPanel.Resources>
            <Label Background="LightGray">◆スタイルで指定</Label>
            <TextBox>オブリガード</TextBox>
            <TextBox>オブラート</TextBox>
            <TextBox>オブザーバー</TextBox>
        </StackPanel>
        <StackPanel>
            <Label Background="LightGray">◆プロパティで指定</Label>
            <TextBox appCtrls:TextBoxGotFocusBehaviors.SelectAllOnGotFocus="True">
                添付ビヘイビアあり
            </TextBox>
            <TextBox>添付ビヘイビアなし</TextBox>
        </StackPanel>
    </StackPanel>
</Window>