在不丢失单元格焦点的情况下刷新 WPF DataGrid

Posted

技术标签:

【中文标题】在不丢失单元格焦点的情况下刷新 WPF DataGrid【英文标题】:Refresh WPF DataGrid without losing cell focus 【发布时间】:2011-07-23 12:07:21 【问题描述】:

我有一个 WPF DataGrid,其中一些数据绑定到 LINQ to SQL 实体类。一列是显示给定航班的飞行时间的时钟,该时间是使用 Flight 的部分类中的逻辑计算的。我有一个计时器,每 2 秒调用一次 datagrid.Items.Refresh 来更新时钟。

刷新工作正常,但现在我正在添加键盘快捷键。使用键盘箭头在单元格中导航可以在定时器关闭的情况下正常工作,但在启用刷新定时器的情况下,获得焦点的单元格(实际上是整个数据网格)会失去焦点。

我需要以某种方式保持焦点(首选)或在 DataGrid 获得焦点时禁用计时器。我什至似乎无法让后者工作。我试过了:

if (!dataGrid.IsFocused)
    dataGrid.Items.Refresh();

if (!dataGrid.IsKeyboardFocused)
        dataGrid.Items.Refresh();

对于计时器,但即使数据网格被聚焦,这些属性也会返回 false。

有什么想法吗?

【问题讨论】:

只存储选中行的索引,刷新后设置selectedIndex 为什么不在绑定实体的定义中异步调用 PropertyChanged 并更改计时器(或部分实体类中的某些逻辑)调用属性。然后您可以将 UpdateSource.OnPropertyChanged 用于您的 DataGridColumn 绑定,这应该(理论上)防止整个 DG 刷新并且只刷新更改的实体(从而解决您的焦点问题并在理论上带来更好的性能)。我错过了什么吗? 【参考方案1】:

最好的方法是不要使用 dataGrid.Items.Refresh() 作为更新机制。听起来底层对象已经单独更新了。如果他们实现了 INotifyPropertyChanged,您应该尝试将列的绑定模式设置为 TwoWay Binding:

<DataGridTextColumn Binding="Binding xyz, Mode=TwoWay"/>

【讨论】:

【参考方案2】:

我认为您可能会获得当前焦点,并且在刷新网格后将所选单元格重新获得其焦点

int index = 11;
myDataGrid.SelectedItem = myDataGrid.Items[index];
myDataGrid.ScrollIntoView(myDataGrid.Items[index]);
DataGridRow dgrow = (DataGridRow)myDataGrid.ItemContainerGenerator.ContainerFromItem(myDataGrid.Items[index]);
dgrow.MoveFocus(new TraversalRequest(FocusNavigationDirection.Next));

也可以查看this,它可能会对您有所帮助

【讨论】:

最初如何获取索引? 如果我是正确的,您要求在刷新之前获取索引,如果是这种情况,那么我要做的是声明一个变量并将其维护在 leftmousedown 或 up 事件处理程序中,并检查 @987654323 @然后以这种方式更新变量我会更新索引【参考方案3】:

您的单元格失去焦点,因为您更改了基础集合 (ItemsSource)。据我所知,没有漂亮的方法可以得到细胞。对于行:

如果您使用 MVVM,您可以记住您的 SelectedItemSelectedIndex 并在重新加载完成后通过绑定将其恢复。首先,这将使您处于正确的位置。两者都有不同的缺点:

SelectedItem 需要更多的工作。如果使用它,请确保在基础对象中覆盖 EqualsGetHashCode。如果您的项目在集合中是第 5 位,并且在重新加载期间出现在它之前的另一行,您仍然会在正确的行中结束 SelectedIndex 是最快的解决方案,但只是一个数字位置。如果您选择条目号 5 并且重新加载在它之前的行中合并,您最终会选择错误的行。

正如我所说,我没有尝试过使用单元格,但您可以先阅读this。也许您可以将其应用于您的问题。

【讨论】:

以上是关于在不丢失单元格焦点的情况下刷新 WPF DataGrid的主要内容,如果未能解决你的问题,请参考以下文章

如何在不丢失表格视图单元格的情况下将现有集合视图添加到表格视图

在WPF DataGrid中按Enter键时将焦点移动到下一个单元格?

如何在不需要额外点击的情况下使 DataGridCheckBoxColumn 可编辑?

如何在不丢失setfocus的情况下将光标设置到文本框的末尾?

如何使用 jquery 在不丢失样式和插件(select2)的情况下刷新 div

有没有办法在不通知 ItemsSource 集合的情况下使用 ObservableCollection 和 MVVM 刷新 WPF DataGrid?