2017-02-28 5 views
1

「GotFocus」イベントが発生したときに特に何かを行うために、ツールボックス内のすべてのテキストボックスを拡張したいとしましょう。 SelectAll()に指示するコード行を実行します。コントロールの機能を拡張する

この動作/イベント処理をすべてのテキストボックスに適用する最も効率的な方法は何ですか?

私はWPFアーセナルの他のコントロールと同様のことをやる予定があるので、TextBoxを例として使用しています。

+0

26の@ 17により示唆されるように動作を使用しては、一つの方法だろう。カスタムTextBoxコントロールを作成し、組み込みのTextBoxコントロールの代わりにこのコントロールを使用する方法もあります。 – mm8

+0

@ mm8実際には、私はすでに、これらのコントロールのいくつかがUserControlsとして設定されていることを言及しています。それぞれ独自のビットとコードがあります。私が実際に何をしているのかは、繰り返しコードを避けることです。私はちょうど私が欲しいコードを取ることができ、これらのコントロールのそれぞれのコードの背後にそれを適用し、それはすべてうまくいくだろうが、私はこの繰り返しをできるだけ避けたいと思いますし、指示は1か所にあります。 – Logan

+0

UserControlsではなく、すべてのUserControlで使用するカスタムTextBoxコントロールクラスに共通コードを配置しないでください。 – mm8

答えて

0

これを実行するには、添付の動作を使用する必要があります。以下は私が現在これを行うために使用しているコードであり、いくつかの奇妙なエッジケースをカバーしています。

public class TextBoxBehaviors 
{ 
    public static readonly DependencyProperty SelectAllOnFocusProperty = DependencyProperty.RegisterAttached("SelectAllOnFocus", typeof(bool), typeof(TextBoxBehaviors), new PropertyMetadata(false, OnSelectAllOnFocusChanged)); 

    public static DependencyProperty GetSelectAllOnFocus(TextBox element) 
    { 
     return (DependencyProperty)element.GetValue(SelectAllOnFocusProperty); 
    } 

    public static void SetSelectAllOnFocus(TextBox element, bool value) 
    { 
     element.SetValue(SelectAllOnFocusProperty, value); 
    } 

    private static void OnSelectAllOnFocusChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) 
    { 
     var comboBox = d as ComboBox; 

     if (comboBox != null) 
     { 
      comboBox.Loaded += ComboBox_Loaded; 
      return; 
     } 

     var textBox = d as TextBox; 

     if (textBox == null) { return; } 

     if ((bool)e.OldValue) 
     { 
      textBox.PreviewMouseDown -= TextBox_PreviewMouseDown; 
      textBox.GotFocus -= TextBox_GotFocus; 
     } 

     if (!(bool)e.NewValue) 
      return; 

     textBox.PreviewMouseDown += TextBox_PreviewMouseDown; 
     textBox.GotFocus += TextBox_GotFocus; 
    } 

    private static void ComboBox_Loaded(object sender, RoutedEventArgs e) 
    { 
     var comboBox = sender as ComboBox; 

     var comboText = comboBox?.Template.FindName("PART_EditableTextBox", comboBox) as TextBox; 

     comboText?.SetValue(SelectAllOnFocusProperty, comboBox.GetValue(SelectAllOnFocusProperty)); 
    } 

    private static void TextBox_GotFocus(object sender, RoutedEventArgs e) 
    { 
     var textBox = sender as TextBox; 
     if (textBox == null) { return; } 

     // We need to dispatch this in case someone is changing the text during the GotFocus 
     // event. In that case, we want to select it all after they're done. 
     Application.Current.Dispatcher.BeginInvoke(DispatcherPriority.Normal, 
                (Action)(() => TextBox_DoSelectAll(textBox))); 
    } 

    private static void TextBox_DoSelectAll(TextBox textBox) 
    { 
     if (!textBox.IsFocused) return; 

     textBox.CaretIndex = textBox.Text.Length; 
     textBox.SelectAll(); 
    } 


    private static void TextBox_PreviewMouseDown(object sender, MouseButtonEventArgs e) 
    { 
     var textBox = sender as TextBox; 
     if (textBox == null) { return; } 

     if (textBox.IsFocused) 
      return; 

     textBox.Focus(); 
     e.Handled = true; // Prevent default TextBox behavior from deselecting text on mouse up 
    } 

}

使用法:

<TextBox beh:TextBoxBehaviors.SelectAllOnFocus="True" /> 

またはすべてのテキストボックスの上に置きます:

<Style TargetType="{x:Type TextBox}"> 
    <Setter Property="beh:TextBoxBehaviors.SelectAllOnFocus" /> 
</Style> 
+0

優秀、私は行動をより多く使用し始めました、彼らは非常に便利です。 – Logan

関連する問題