WPF SelectedItem绑定到源不影响键盘导航

WPF SelectedItem绑定到源不影响键盘导航,wpf,datagrid,Wpf,Datagrid,好的,我将使用一个典型的绑定到我的ViewModel。无论是源代码还是目标代码,它都能很好地工作。vm集合是一个ObservableCollection,它是初始化的,从不修改任何setter public ObservableCollection<Statement> StatementsList { get; } = new(); #region SelectedStatement private Statement _selectedStatement

好的,我将使用一个典型的绑定到我的ViewModel。无论是源代码还是目标代码,它都能很好地工作。vm集合是一个ObservableCollection,它是初始化的,从不修改任何setter

    public ObservableCollection<Statement> StatementsList { get; } = new();

    #region SelectedStatement
    private Statement _selectedStatement;
    public Statement SelectedStatement
    {
        get => _selectedStatement;
        set => Set(ref _selectedStatement, value, nameof(SelectedStatement));
    }
    #endregion SelectedStatement
我可以从ViewModel中设置SelectedStatement,UI可以很好地更新。我可以观察DataGrid的SelectionChanged事件,并确认添加的项目和删除的项目完全符合预期

然后,我使用鼠标选择一个不同的行,并使用我的搜索功能使用SelectedItem=some语句选择另一行,这会再次以视觉方式完美地选择该行,并再次通过SelectionChanged事件确认。我的视图模型中的SelectedStatement具有正确的值

然后,奇怪开始了。我按下键盘上的向下箭头

您可能希望选择所选语句后的下一行,但选择之前使用鼠标选择的项目后的下一行。这就像DataGrid中的键盘响应代码没有通过VM识别先前的新行选择

有人见过这种行为吗?我做WPF开发已经很多年了,我见过很多奇怪的WPF bug,但这一个我从来没有注意过


请注意,在DataGrid上IsSynchronizedWithCurrentItem=True。我试着把它设为false,就像暗中捅了一刀,但行为没有改变。我还尝试更改SelectedItem属性以包装对GetDefaultCollectionView的调用,并通过collection视图获取/更改所选项目,而不是使用SelectedItem的绑定。行为是相同的。

选择一个项目本质上就是设置IsSelected=true。 设置此属性不会以任何方式影响焦点到选定元素的转换。 当通过键盘进行控制时,会从具有焦点的元素进行转换

您可以将SelectionChanged处理添加到选择器列表框、DataGrid,。。。并在其中通过SelectedIndex中的索引执行到所选项目的焦点转换

此类处理程序的一个示例:

    private void OnSelectionChanged(object sender, SelectionChangedEventArgs e)
    {
        if (sender is Selector selector)
        {
            int index = selector.SelectedIndex;
            if (index >=0)
            {
               var element = selector.ItemContainerGenerator.ContainerFromIndex(index);
                if (element is UIElement uiElement)
                    uiElement.Focus();
            }
        }
    }

您需要提供如何选择项目的可复制示例。您确定SelectedStatement的setter没有设置为您期望的值以外的其他值吗?我通过SelectedStatement=some语句设置它。正如我所说的,它工作得非常完美,DataGrid按照预期进行了可视化更改,SelectionChanged甚至确认了新语句已被选中。新对象位于ItemsSource中,因为否则这一切都不起作用!