如何在wpf MVVM

时间:2017-05-18 12:43:31

标签: c# wpf xaml mvvm

我在堆叠面板上有一些控制权 当我右键单击面板时,它会给我一个上下文菜单,我可以编辑这些控件的文本 在这里,我使用TextBlock显示数据,使用TextBox编辑数据(当TextBox可见时,TextBlock会折叠,反之亦然)
我想选择TextBox的所有文本,并在TextBox可见时将其聚焦。

我尝试过使用互动。但没有成功:(
有没有办法做到这一点?
例如:当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>

4 个答案:

答案 0 :(得分: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(),或者按照here所述的更多MVVM方式处理键盘焦点

答案 1 :(得分:0)

有一个可以使用的事件,并且它适用于所有UIElement UIElement.IsVisibleChanged 之后,您必须在文本框中进行焦点并选择像这样的文本

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

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

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

How to set focus to textbox using MVVM?

答案 2 :(得分: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文件)中将bool属性绑定到我们在上面创建的扩展名。

<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>

  1. 在视图模型类中,定义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
    }
    

答案 3 :(得分:0)

您所要求的通常是首选的TextBox行为。您可以在App.xaml.cs all 文本框中更改此设置:

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();
    }
}