ネタ元:WPFのテキストボックスをフォーカスがくると全選択状態にしたい
ネタ元のエントリで3パターンの実装方法が示されています。
- TextBoxを継承
- トリガーでなんとか
- イベントで
1は、TextBoxがフォーカスを取得したタイミングでSelectAllを呼ぶ感じでしょうか。
利点は、同じような機能を持ったTextBoxが沢山欲しいときに再利用が効くってところかな?
2は、なんとかなるかな…?
イベントトリガーでフォーカスを得た時にSelectionStartとSelectionLengthを設定すればいけるんだろうか?未検証。
3は、GotFocusイベントあたりでSelectAllを呼べばいける。
3のメリットはお手軽なので、さくっとできる。でも再利用はしにくい。
1は大げさで、3は再利用が効かないという悩みはよくあります。今までは再利用をすすめるために1を採用して、オレオレコントロール群が出来上がって充実した開発ライフを送ることが出来ました。WPFでも可能です。
ただ、もうちょっと洗練された方法がWPFだと出来ます。3のお手軽さを保ちつつ、1のような大げさなことはしたくないというときは、添付Behaviorを検討するのがいいと思います。
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
namespace Sample
{
public class TextBoxBehaviors
{
[AttachedPropertyBrowsableForType(typeof(TextBox))]
public static bool GetIsFocusSelect(DependencyObject obj)
{
return (bool)obj.GetValue(IsFocusSelectProperty);
}
[AttachedPropertyBrowsableForType(typeof(TextBox))]
public static void SetIsFocusSelect(DependencyObject obj, bool value)
{
obj.SetValue(IsFocusSelectProperty, value);
}
// Trueだとフォーカス取得時にテキストの全選択を行う
public static readonly DependencyProperty IsFocusSelectProperty =
DependencyProperty.RegisterAttached("IsFocusSelect", typeof(bool), typeof(TextBoxBehaviors), new UIPropertyMetadata(false, IsFocusSelectChanged));
private static void IsFocusSelectChanged(DependencyObject sender, DependencyPropertyChangedEventArgs e)
{
var textBox = sender as TextBox;
if (textBox == null) return;
// 設定された値を見てイベントを登録・削除
var newValue = (bool)e.NewValue;
var oldValue = (bool)e.OldValue;
if (oldValue)
{
textBox.GotFocus -= textBox_GotFocus;
}
if (newValue)
{
textBox.GotFocus += textBox_GotFocus;
}
}
static void textBox_GotFocus(object sender, RoutedEventArgs e)
{
var textBox = sender as TextBox;
if (textBox == null) return;
// フォーカスがきたら選択
textBox.SelectAll();
}
}
}
こんなのを作っておけば
<Window x:Class="WpfApplication1.Window1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:sample="clr-namespace:Sample"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="Window1" Height="300" Width="300">
<StackPanel>
<TextBox Name="textBox" sample:TextBoxBehaviors.IsFocusSelect="True" />
<Button Content="AA" Click="Button_Click" />
</StackPanel>
</Window>
こんな風に使える。
因みに、この実装だとTabキーによるフォーカス移動はOKだけど、マウスでフォーカス移動してTextBoxにフォーカスがきた場合は、全選択の後、速やかにマウスでクリックした位置にキャレットが移動してしまい選択状態が解除されてしまう悲しさがあります。
いまいち・・・?