假设我想扩展工具箱中的所有文本框,以便在引发“GotFocus”事件时执行某些操作。 比如说,运行一行代码指示他们选择SelectAll();
对于我的所有TextBox,我能将这种行为/处理事件的最有效方法是什么?
我只是使用TextBox作为示例,因为我计划在我的WPF武器库中与其他控件做类似的事情。
答案 0 :(得分: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>