初始焦点和全选行为

时间:2011-10-18 14:32:16

标签: wpf focus

我有一个嵌套在窗口内的用户控件,该窗口充当对话框显示的shell。我在shell窗口中忽略焦点,在托管用户控件中,我使用FocusManager将初始焦点设置为命名元素(文本框),如下所示。

这样做,将光标设置在指定文本框的开头;但是我想要选择所有文本。

TextBoxSelectionBehavior类(下面)通常就是这样,但在这种情况下不是这样。是否有一个简单的xaml修复程序可以在初始焦点上选择指定文本框中的文本?

干杯,
Berryl

TextBox选择行为

// in app startup
TextBoxSelectionBehavior.RegisterTextboxSelectionBehavior();

/// <summary>
/// Helper to select all text in the text box on entry
/// </summary>
public static class TextBoxSelectionBehavior
{
    public static void RegisterTextboxSelectionBehavior()
    {
        EventManager.RegisterClassHandler(typeof(TextBox), UIElement.GotFocusEvent, new RoutedEventHandler(OnTextBox_GotFocus));
    }

    private static void OnTextBox_GotFocus(object sender, RoutedEventArgs e)
    {
        var tb = (sender as TextBox);
        if (tb != null)
            tb.SelectAll();
    }
}

托管的UserControl

<UserControl   
<DockPanel KeyboardNavigation.TabNavigation="Local" 
    FocusManager.FocusedElement="{Binding ElementName=tbLastName}" >

            <TextBox x:Name="tbLastName" ... />

停止间隙解决方案

根据下面的Rachel的评论,我放弃了FocusManger,转而支持一些代码:

tbLastName.Loaded += (sender, e) => tbLastName.Focus();

尽管如此,仍然会喜欢一种简单而常见的苦差事的声明式方法......

2 个答案:

答案 0 :(得分:14)

我通常使用AttachedProperty来使TextBox在焦点上突出显示其文本。它像

一样使用
<TextBox local:HighlightTextOnFocus="True" />

附加财产的代码

public static readonly DependencyProperty HighlightTextOnFocusProperty =
    DependencyProperty.RegisterAttached("HighlightTextOnFocus", 
    typeof(bool), typeof(TextBoxProperties),
    new PropertyMetadata(false, HighlightTextOnFocusPropertyChanged));


[AttachedPropertyBrowsableForChildrenAttribute(IncludeDescendants = false)]
[AttachedPropertyBrowsableForType(typeof(TextBox))]
public static bool GetHighlightTextOnFocus(DependencyObject obj)
{
    return (bool)obj.GetValue(HighlightTextOnFocusProperty);
}

public static void SetHighlightTextOnFocus(DependencyObject obj, bool value)
{
    obj.SetValue(HighlightTextOnFocusProperty, value);
}

private static void HighlightTextOnFocusPropertyChanged(
        DependencyObject obj, DependencyPropertyChangedEventArgs e)
{
    var sender = obj as UIElement;
    if (sender != null)
    {
        if ((bool)e.NewValue)
        {
            sender.GotKeyboardFocus += OnKeyboardFocusSelectText;
            sender.PreviewMouseLeftButtonDown += OnMouseLeftButtonDownSetFocus;
        }
        else
        {
            sender.GotKeyboardFocus -= OnKeyboardFocusSelectText;
            sender.PreviewMouseLeftButtonDown -= OnMouseLeftButtonDownSetFocus;
        }
    }
}

private static void OnKeyboardFocusSelectText(
    object sender, KeyboardFocusChangedEventArgs e)
{
    var textBox = e.OriginalSource as TextBox;
    if (textBox != null)
    {
        textBox.SelectAll();
    }
}

private static void OnMouseLeftButtonDownSetFocus(
    object sender, MouseButtonEventArgs e)
{
    TextBox tb = FindAncestor<TextBox>((DependencyObject)e.OriginalSource);

    if (tb == null)
        return;

    if (!tb.IsKeyboardFocusWithin)
    {
        tb.Focus();
        e.Handled = true;
    }
}

static T FindAncestor<T>(DependencyObject current)
    where T : DependencyObject
{
    current = VisualTreeHelper.GetParent(current);

    while (current != null)
    {
        if (current is T)
        {
            return (T)current;
        }
        current = VisualTreeHelper.GetParent(current);
    };
    return null;
}

修改

根据以下评论,如何摆脱FocusManager.FocusedElement并在tb.Focus()的{​​{1}}事件中设置tb.SelectAll()Loaded?< / p>

答案 1 :(得分:3)

如上所述,您可以为Loaded事件添加事件处理程序以设置焦点并选择所有文本:

public partial class Window1 : Window
{
    public Window1()
    {
        InitializeComponent();

        base.DataContext = new Person { FirstName = "Joe", LastName = "Smith" };

        base.Loaded += delegate
        {
            this._firstNameTextBox.Focus();
            this._firstNameTextBox.SelectAll();
        };
    }
}