WPF MVVM在两个文本框之间切换焦点

本文关键字:文本 之间 焦点 两个 MVVM WPF | 更新日期: 2023-09-27 18:02:20

我在MVVM中有一个WPF应用程序,有2个文本框,我想动态设置焦点

在WPF中,我为文本框"NodeBarcode_1"answers"NodeBarcode_2"创建了2个数据触发器

 <DataTrigger Binding="{Binding NodeBarcode_1_GetFocusNow}" Value="True">
                    <Setter Property="FocusManager.FocusedElement" Value ="{Binding ElementName=NodeBarcode_1}"/>
                </DataTrigger>
                <DataTrigger Binding="{Binding NodeBarcode_2_GetFocusNow}" Value="True">
                    <Setter Property="FocusManager.FocusedElement" Value ="{Binding ElementName=NodeBarcode_2}"/>
                </DataTrigger>

在视图模型中,我创建了两个布尔变量:

public const string NodeBarcode_1_GetFocusNowPropertyName = "NodeBarcode_1_GetFocusNow";
private bool _NodeBarcode_1_GetFocusNow = false;
public bool NodeBarcode_1_GetFocusNow
{
    get
    {
        return _NodeBarcode_1_GetFocusNow;
    }
    set
    {
        if (_NodeBarcode_1_GetFocusNow == value)
        {
            return;
        }
        _NodeBarcode_1_GetFocusNow = value;
        RaisePropertyChanged(NodeBarcode_1_GetFocusNowPropertyName);
    }
}
public const string NodeBarcode_2_GetFocusNowPropertyName = "NodeBarcode_2_GetFocusNow";
private bool _NodeBarcode_2_GetFocusNow = false;
public bool NodeBarcode_2_GetFocusNow
{
    get
    {
        return _NodeBarcode_2_GetFocusNow;
    }
    set
    {
        if (_NodeBarcode_2_GetFocusNow == value)
        {
            return;
        }
        _NodeBarcode_2_GetFocusNow = value;
        RaisePropertyChanged(NodeBarcode_2_GetFocusNowPropertyName);
    }
}

并且我创建了两个方法,当用户在文本框

中输入条形码时执行
private void NodeBarcode_1_Execute(EventArgs e)
{
    try
    {
        IProduct NodeObj = ObjectFactory<IProduct>.Create("Node");
        NodeObj.Barcode = NodeBarcode_1_txt;
        NodeObj.Validation();
        labelAppObj.AddProduct(NodeObj);
        NodeBarcode_2_GetFocusNow = true;
    }
    catch (Exception ex)
    {
        MessageBox.Show(ex.Message, "Error", MessageBoxButton.OK, MessageBoxImage.Error);
        NodeBarcode_1_txt = string.Empty;
    }

}
private void NodeBarcode_2_Execute(EventArgs e)
{
    try
    {
        IProduct NodeObj = ObjectFactory<IProduct>.Create("Node");
        NodeObj.Barcode = NodeBarcode_2_txt;
        NodeObj.Validation();
        labelAppObj.AddProduct(NodeObj);
        NodeBarcode_1_GetFocusNow = true;

    }
    catch (Exception ex)
    {
        MessageBox.Show(ex.Message, "Error", MessageBoxButton.OK, MessageBoxImage.Error);
        NodeBarcode_2_txt = string.Empty;
    }
}

当用户扫描文本框"NodeBarcode_1"中的第一个条形码时,焦点转到"NodeBarcode_2"。没有问题。但是当用户扫描"NodeBarcode_2"中的下一个条形码时,我希望焦点回到"NodeBarcode_1"。但这并没有发生。

什么会导致这个问题?

WPF MVVM在两个文本框之间切换焦点

您必须重置您的状态,以便使触发器像这样连续工作:

private void NodeBarcode_1_Execute(EventArgs e) {
    try {
        IProduct NodeObj = ObjectFactory<IProduct>.Create("Node");
        NodeObj.Barcode = NodeBarcode_1_txt;
        NodeObj.Validation();
        labelAppObj.AddProduct(NodeObj);
        NodeBarcode_1_GetFocusNow = false; // <--- Here
        NodeBarcode_2_GetFocusNow = true;
    }
    catch (Exception ex) {
        MessageBox.Show(ex.Message, "Error", MessageBoxButton.OK, MessageBoxImage.Error);
        NodeBarcode_1_txt = string.Empty;
    }
}
private void NodeBarcode_2_Execute(EventArgs e) {
    try {
        IProduct NodeObj = ObjectFactory<IProduct>.Create("Node");
        NodeObj.Barcode = NodeBarcode_2_txt;
        NodeObj.Validation();
        labelAppObj.AddProduct(NodeObj);
        NodeBarcode_1_GetFocusNow = true;
        NodeBarcode_2_GetFocusNow = false; // <--- Here
    }
    catch (Exception ex) {
        MessageBox.Show(ex.Message, "Error", MessageBoxButton.OK, MessageBoxImage.Error);
        NodeBarcode_2_txt = string.Empty;
    }
}

编辑

我做了一个最小的例子。我并没有更改代码,所以这个解决方案必须适用于你的问题,除非你没有列出所有的事实。

Xaml

 <StackPanel Grid.Row="1">
            <TextBox x:Name="NodeBarcode_1" Background="Green">
                <TextBox.Style>
                    <Style TargetType="TextBox">
                        <Style.Triggers>
                            <DataTrigger Binding="{Binding NodeBarcode_1_GetFocusNow}" Value="True">
                                <Setter Property="FocusManager.FocusedElement" Value ="{Binding ElementName=NodeBarcode_1}"/>
                            </DataTrigger>
                            <DataTrigger Binding="{Binding NodeBarcode_2_GetFocusNow}" Value="True">
                                <Setter Property="FocusManager.FocusedElement" Value ="{Binding ElementName=NodeBarcode_2}"/>
                            </DataTrigger>
                        </Style.Triggers>
                    </Style>
                </TextBox.Style>
            </TextBox>
            <TextBox x:Name="NodeBarcode_2" Background="Blue">
                <TextBox.Style>
                    <Style TargetType="TextBox">
                        <Style.Triggers>
                            <DataTrigger Binding="{Binding NodeBarcode_1_GetFocusNow}" Value="True">
                                <Setter Property="FocusManager.FocusedElement" Value ="{Binding ElementName=NodeBarcode_1}"/>
                            </DataTrigger>
                            <DataTrigger Binding="{Binding NodeBarcode_2_GetFocusNow}" Value="True">
                                <Setter Property="FocusManager.FocusedElement" Value ="{Binding ElementName=NodeBarcode_2}"/>
                            </DataTrigger>
                        </Style.Triggers>
                    </Style>
                </TextBox.Style>
            </TextBox>
            <Button Content="Simulate first" Click="Button1_OnClick"></Button>
            <Button Content="Simulate second" Click="Button2_OnClick"></Button>
        </StackPanel>

private void Button1_OnClick(object sender, RoutedEventArgs e) {
            try {
                NodeBarcode_1_GetFocusNow = false; // <--- Here
                NodeBarcode_2_GetFocusNow = true;
            }
            catch (Exception ex) {
                MessageBox.Show(ex.Message, "Error", MessageBoxButton.OK, MessageBoxImage.Error);
            }
        }
        private void Button2_OnClick(object sender, RoutedEventArgs e) {
            try {
                NodeBarcode_1_GetFocusNow = true;
                NodeBarcode_2_GetFocusNow = false; // <--- Here
            }
            catch (Exception ex) {
                MessageBox.Show(ex.Message, "Error", MessageBoxButton.OK, MessageBoxImage.Error);
            }
        }

这两个按钮现在将正确地切换焦点。