2011-03-26 43 views
8

我有一个WPF DataGrid,其中一些数据绑定到LINQ to SQL实体类。一栏是一个时钟,显示给定航班的空中飞行时间,这是使用飞行部分班级中的逻辑计算的。我有一个计时器每2秒钟调用一次datagrid.Items.Refresh来更新时钟。刷新WPF DataGrid而不会丢失细胞聚焦

刷新工作正常,但现在我添加键盘快捷键。使用键盘箭头浏览单元格可以在关闭计时器的情况下正常工作,但启用了刷新计时器后,聚焦的单元格(实际上是整个数据网格)失去了焦点。

我需要以某种方式保持焦点(首选)或禁用定时器,只要DataGrid的重点。我甚至不能让后者工作。我已经试过:

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

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

定时器,但这些属性返回即使在数据网格的重点是假的。

任何想法?

+0

只存储选定行的索引,刷新后设置selectedIndex – Hukam 2011-03-26 14:16:46

+0

为什么不只是在绑定实体的定义中异步调用PropertyChanged,并让定时器(或部分实体类中的某些逻辑)调用属性发生更改。然后你可以使用UpdateSource。OnPropertyChanged用于DataGridColumn绑定,这应该(理论上)阻止整个DG刷新并仅刷新更改的实体(从而解决您的焦点问题,并导致更好的性能)。我错过了什么吗? – William 2012-12-14 01:25:08

回答

0

我想你可能会看到目前的重点和后格刷新给选定的单元格回到它的焦点像

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出它可以帮助你

+1

最初如何获得指数? – Anders 2011-03-26 15:14:10

+0

如果我是正确的,你要求在刷新前获取索引,如果是这种情况,那么我所做的是我声明一个变量并将其保存在leftmousedown或up事件处理程序中,并检查如果'datagrid.SelectedIndex> = 0'那么以这种方式更新变量,我会更新索引 – 2011-03-26 17:21:55

2

最好的办法是不使用dataGrid.Items.Refresh()作为更新机制。这听起来像是底层对象已经单独更新了。如果他们执行INotifyPropertyChanged,你应该尝试设置绑定模式为科拉姆为双向绑定:因你而改变底层集合(的ItemsSource)

<DataGridTextColumn Binding="{Binding xyz, Mode=TwoWay}"/> 
0

你的细胞失去焦点。据我所知,没有美丽的方式来获得细胞。对于该行:

如果您使用MVVM,则可以记住您的SelectedItemSelectedIndex,并在通过绑定完成重新加载后将其恢复。那会让你排在第一位,开始。两者都有不同的缺点:

  • SelectedItem需要更多的工作。如果您使用它,请确保您覆盖底层对象中的EqualsGetHashCode。如果您的物品在集合中的数量为5,并且在重新加载期间出现另一行,则仍然会在最右边
  • SelectedIndex是最快的解决方案,但它只是一个数字位置。如果选择条目编号5,并且重新加载在它之前的行中合并,则最终将选择错误的行。

正如我所说的,我没有尝试使用这些单元格,但是您可以阅读this作为开始。也许你可以将它应用于你的问题。