如何在WPF MVVM中选择文本框的文本

3
我有一个StackPanel控件。
当我右键单击该面板时,会出现一个上下文菜单,我可以编辑这些控件的文本。
在此处,我使用TextBlock来显示数据,并使用TextBox来编辑数据(当TextBox可见时,TextBlock变为折叠状态,反之亦然)
我希望在TextBox可见时选择所有文本并将其聚焦。

我尝试使用Interaction,但没有成功:(
有没有办法做到这一点?
例如:当TextBox可见时,我可以在我的ViewModel中触发某些命令,并从我的ViewModel中选择所有文本。

<TextBlock Text="{Binding MachineResponseText}" Visibility="{Binding IsEditing, Converter={StaticResource BoolToVisibilityConverter}, ConverterParameter=true}"/>
<TextBox x:Name="MachineResponseTextBox" Text="{Binding MachineResponseText, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" Visibility="{Binding IsEditing, Converter={StaticResource BoolToVisibilityConverter}}">
    <TextBox.Style>
        <Style TargetType="TextBox">
            <Style.Triggers>
                <Trigger Property="IsVisible" Value="True">
                    <!--Is there any way to select all the text when this textbox is visible?-->
                </Trigger>
            </Style.Triggers>
        </Style>
    </TextBox.Style>
</TextBox>

你想要的是“突出显示”TextBox中的所有文本,因此你的VM应该不涉及此事。在我看来,这听起来像是一个代码后台解决方案,因为VM并不真正关心文本是否被选中。除非我误解了你的意思? - XAMlMAX
是的,那是真的。我不必使用虚拟机。但是我该如何突出显示文本并将键盘聚焦在文本字段上? - Ali Akber
TextBox有一个SelectedText属性,你可以在gotFocus事件上设置它。但如果这只是在编辑模式之间切换,为什么不操作TextBox上的IsEnabled属性呢? - XAMlMAX
可能是如何在WPF TextBox中自动选择所有文本?的重复问题。 - Herohtar
4个回答

0
如果你想使用MVVM设计模式,我建议这样做。
  1. 首先,您需要创建以下扩展方法。

    public static class IsSelectTextExtension
    {
    public static readonly DependencyProperty IsSelectTextProperty = DependencyProperty.RegisterAttached("IsSelectText", typeof(bool), typeof(IsSelectTextExtension), new UIPropertyMetadata(false, OnIsSelectTextPropertyChanged));
    
    public static bool GetIsSelectText(DependencyObject obj)
    {
        return (bool)obj.GetValue(IsSelectTextProperty);
    }
    
    public static void SetIsSelectText(DependencyObject obj, bool value)
    {
        obj.SetValue(IsSelectTextProperty, value);
    }
    
    private static void OnIsSelectTextPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
    {
        var uie = (TextBox)d;
        if ((bool)e.NewValue)
        {
            uie.SelectAll();
        }
    }
    }
    
    1. 将命名空间包含到视图中,并在您的视图(.xaml 文件)中将布尔属性绑定到我们上面创建的扩展。

<Window x:Class="POS.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:local="clr-namespace:WpfExample"
        xmlns:extension="clr-namespace:WpfExample.Extension"
        mc:Ignorable="d"
        Title="MainWindow" Height="450" Width="800">
    <Grid>
        <TextBox extension:IsSelectTextExtension.IsSelectText="{Binding IsSelectText}"/>
    </Grid>
</Window>

  • 在视图模型类中,定义IsSelectText属性,并根据您的要求更改其值。

    public class MainWindowViewModel: INotifyPropertyChanged
    {
    private bool _isSelectText;
    public bool IsSelectText
    {
        get
        {
            return this._isSelectText;
        }
        set
        {
            _isSelectText = value;
            OnPropertyChanged(nameof(IsSelectText));
        }
    }
    
    public NewSaleViewModel()
    {
    }
    
    #region INotifyPropertyChanged Implimentations
    
    public event PropertyChangedEventHandler PropertyChanged;
    
    protected virtual void OnPropertyChanged(string propertyName)
    {
        if (this.PropertyChanged != null)
            this.PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
    }
    
    #endregion
    }
    

  • 0
    你所要求的通常是首选的TextBox行为。你可以在App.xaml.cs中更改所有文本框的行为:
    protected override void OnStartup(StartupEventArgs e)
    {
        // ...
        EventManager.RegisterClassHandler(typeof(TextBox),
            UIElement.GotFocusEvent, new RoutedEventHandler(OnTextBoxGotFocus));
    }
    
    private static void OnTextBoxGotFocus(object sender, RoutedEventArgs e)
    {
        if (sender is TextBox textBox && !textBox.IsReadOnly)
        {
            textBox.SelectAll();
        }
    }
    

    0
    这不是完整的答案,更像是指引正确方向。
    在您的文本框中添加 GotKeyboardFocus 处理程序并运行 textbox.SelectAll(),即:
    XAML 部分:
    <StackPanel>
        <Button>B1</Button>
        <TextBox Text="Test123" GotKeyboardFocus="TextBox_GotKeyboardFocus"/>
        <TextBlock>123</TextBlock>
        <Button>B2</Button>
    </StackPanel>
    

    代码后台部分:

    private void TextBox_GotKeyboardFocus(object sender, KeyboardFocusChangedEventArgs e)
    {
        var textBox = (TextBox) sender;
        if (textBox.SelectionLength == 0)
        {
            textBox.SelectAll();
        }
    }
    

    在切换到编辑模式时,您可能还需要通过调用TextBox.Focus()来处理键盘焦点,或者按照更多的 MVVM 方式,如此处所述here


    -1

    有一个事件可以使用,它适用于所有UIElementUIElement.IsVisibleChanged之后,您必须将焦点放在文本框中并选择文本,如下所示

    private void TextBox_IsVisibleChanged(object sender, DependencyPropertyChangedEventArgs e)
    {
        this.myTextBox.Focus();
        this.myTextBox.SelectAll();
    }
    

    这是一个代码后台版本,您可以通过在视图模型中触发事件来在MVVM上下文中执行相同的操作。

    如果您想在MVVM中设置文本框焦点,此stackoverflow帖子可能会对您有所帮助。

    如何使用MVVM设置文本框焦点?


    网页内容由stack overflow 提供, 点击上面的
    可以查看英文原文,
    原文链接