XAML 在窗口初始化后聚焦TextBox并选择所有文本

dnph8jn4  于 2023-09-28  发布在  其他
关注(0)|答案(3)|浏览(103)

当一个新窗口打开时,我想聚焦一个特定的文本框并选择其中的整个文本。我在这个教程的基础上尝试了一下:https://blogs.msdn.microsoft.com/argumentnullexceptionblogpost/2013/04/12/a-simple-selectall-behavior-for-textboxes/
为了聚焦元素,我在我的网格中使用了这个:

<Grid d:DataContext="{StaticResource DesignTimeLayerViewModel1}" FocusManager.FocusedElement="{Binding ElementName=LayerNameInput}">

并尝试了一个交互行为:

<TextBox x:Name="LayerNameInput"
    Text="{Binding MapLayerName, UpdateSourceTrigger=PropertyChanged}"
    VerticalContentAlignment="Center"
    Width="240">
    <i:Interaction.Behaviors>
        <behaviors:SelectAllTextBoxBehavior></behaviors:SelectAllTextBoxBehavior>
    </i:Interaction.Behaviors>
</TextBox>

行为代码:

public class SelectAllTextBoxBehavior : Behavior<TextBox>
{
    protected override void OnAttached()
    {
        base.OnAttached();
        this.AssociatedObject.GotFocus += this.OnTextBoxGotFocus;
    }

    protected override void OnDetaching()
    {
        this.AssociatedObject.GotFocus -= this.OnTextBoxGotFocus;
        base.OnDetaching();
    }

    private void OnTextBoxGotFocus(object sender, RoutedEventArgs e)
    {
        this.AssociatedObject.SelectAll();
    }
}

问题是绑定。创建窗口时,行为会正确触发,但实际上TextBox中没有文本。然后初始化TextBox并将文本设置为绑定变量的值,选择将丢失。如果我通过多次使用Tab来重新聚焦TextBox,它可以正常工作。
如何在创建窗口时聚焦TextBox并选择其整个文本?没有大量的代码在背后?
提前感谢!

t1qtbnec

t1qtbnec1#

你可以使用“window_loaded”事件来聚焦你的文本框,这里有一个例子:

private void window_Loaded(object sender, RoutedEventArgs e)
    {
        textBox.Focus();
        textBox.SelectAll();
    }
unftdfkk

unftdfkk2#

我用一个变通方法解决了这个问题。在窗口启动期间设置TextBox的初始文本时,将激发OnTextBoxTextChanged事件。我只是抓住它,选择文本,然后删除事件。
与你的答案相比,黑暗圣堂武士的好处是,当我再次聚焦文本框时,例如。使用tab键,再次选择整个文本。

protected override void OnAttached()
    {
        base.OnAttached();
        AssociatedObject.GotFocus += OnTextBoxGotFocus;
        AssociatedObject.TextChanged += OnTextBoxTextChanged;
    }

    protected override void OnDetaching()
    {
        AssociatedObject.GotFocus -= OnTextBoxGotFocus;
        AssociatedObject.TextChanged -= OnTextBoxTextChanged;
        base.OnDetaching();
    }

    private void OnTextBoxGotFocus(object sender, RoutedEventArgs e)
    {
        AssociatedObject.SelectAll();
    }

    private void OnTextBoxTextChanged(object sender, RoutedEventArgs e)
    {
        AssociatedObject.SelectAll();
        AssociatedObject.TextChanged -= OnTextBoxTextChanged;
    }
mec1mxoz

mec1mxoz3#

为此,我创建了一个附加属性。

public static class TextBoxExtensions
{
    /// <summary>
    /// An attached property that, when set to true, causes a TextBox to select
    /// all its text when it receives focus. Assumes that the TextBox's lifecycle
    /// matches its parent user control's lifecycle.
    /// </summary>
    public static readonly DependencyProperty SelectTextOnFocusProperty = DependencyProperty.RegisterAttached(
        "SelectTextOnFocus",
        typeof(bool),
        typeof(TextBoxExtensions),
        new PropertyMetadata(false, OnSelectTextOnFocusChanged));

    public static bool GetSelectTextOnFocus(TextBox textBox) => (bool)textBox.GetValue(SelectTextOnFocusProperty);

    public static void SetSelectTextOnFocus(TextBox textBox, bool value) => textBox.SetValue(SelectTextOnFocusProperty, value);

    private static void OnSelectTextOnFocusChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
    {
        if (d is TextBox textBox && e.NewValue is bool b)
        {
            if (b) textBox.GotFocus += TextBox_GotFocus;
            else textBox.GotFocus -= TextBox_GotFocus;
        }

        void TextBox_GotFocus(object sender, RoutedEventArgs e)
        {
            textBox.SelectAll();
        }
    }
}

您在XAML中声明扩展的名称空间,我使用“ext”作为扩展。
然后,要应用它,只需设置属性。

<TextBox x:Name="_quantity" ext:TextBoxExtensions.SelectTextOnFocus="True" Grid.Column="1" Text="{Binding Quantity, UpdateSourceTrigger=PropertyChanged}" />

如果你只是在一个地方这样做,那就太过分了,但是如果你有一个表单,你想在很多文本框上都有这样的行为,那么这个带有样式的表单就很容易了。

相关问题