2011-03-26 58 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作爲開始。也許你可以將它應用於你的問題。