2012-02-27 71 views
3

.NET 4的WPF的DataGrid MVVM如何把重點放在新行單元格中的WPF的DataGrid

用戶單擊Add按鈕觸發的視圖模型的命令。在viewmodel命令execute中,我將一個新對象添加到網格綁定的視圖模型的viewcollection中。新行出現在我的網格中。不過,我也希望將焦點發送到新行中的第一個可編輯單元格。

我甚至「騙」 MVVM,加在我的視圖模型,視圖聽,知道什麼時候把重點放在新行的事件。

我已經搜查,但沒有運氣。我希望,當我遇到這個傳來:

Datagrid Set focus on newly added row

導致

http://social.msdn.microsoft.com/forums/en-US/wpf/thread/63974f4f-d9ee-45af-8499-42f29cbc22ae

但是,其他人報告這個問題,沒有人回答的是如何應對虛擬化行爲的網格。新添加的行尚未創建。因此,GetCells調用經常失敗。如果ScrollIntoView是必需的,那麼它更有可能失敗。

我已經迷上一噸的事件,包括LoadingRow和RequestBringIntoView沒有運氣的。根據我掛鉤的事件,我設法能夠獲得對單元格的引用。但後來我收到一個錯誤:「內容生成過程中無法調用StartAt」。但是當我調用單元格的BeginEdit時,我檢查了ItemContainerGenerator的狀態,並且它是ContainersGenerated。

回答

1

這裏是將焦點設置到程序中的特定小區的一種方法:

DataGridCell cell = GetCell(rowIndex, colIndex); 
cell.Focus; 

請參閱有關詳細信息,下面article上GetCell()。

+1

???你甚至讀過我的問題嗎?我已經包含了一個指向該頁面的鏈接,GetCell的問題是,如果單元格還沒有創建,它就無法工作。 – happyfirst 2012-02-28 00:36:47

+0

嘗試ScrollIntoView – 2012-02-28 14:06:32

+0

這一工程之前調用dg.UpdateLayout()!!!!早些時候,我發現一個修復,我不得不「調度」一個函數調用,優先級正常,並且工作。但到目前爲止,在ScrollIntoView之前調用UpdateLayout似乎是可靠的。謝謝! – happyfirst 2012-02-29 00:48:07

0

這似乎爲我工作:

using System.Windows.Controls; 
    using System.Windows.Controls.Primitives; 
    using System.Windows.Media; 

    private void SetFocusOnNewRow(DataGrid theDataGrid, Int32 columnIndex) 
    { 
     theDataGrid.UnselectAll(); 
     theDataGrid.UpdateLayout(); 

     Int32 newRowIndex = theDataGrid.Items.Count - 1; 
     theDataGrid.ScrollIntoView(theDataGrid.Items[newRowIndex]); 
     DataGridRow newDataGridRow = theDataGrid.ItemContainerGenerator.ContainerFromIndex(newRowIndex) as DataGridRow; 

     DataGridCellsPresenter newDataGridCellsPresenter = GetVisualChild<DataGridCellsPresenter>(newDataGridRow); 
     if (newDataGridCellsPresenter != null) 
     { 
      DataGridCell newDataGridCell = newDataGridCellsPresenter.ItemContainerGenerator.ContainerFromIndex(columnIndex) as DataGridCell; 
      if (newDataGridCell != null) 
       newDataGridCell.Focus(); 
     } 
    } 

    static T GetVisualChild<T>(Visual parent) where T : Visual 
    { 
     T child = default(T); 
     int numVisuals = VisualTreeHelper.GetChildrenCount(parent); 
     for (int i = 0; i < numVisuals; i++) 
     { 
      Visual v = (Visual)VisualTreeHelper.GetChild(parent, i); 
      child = v as T; 
      if (child == null) 
      { 
       child = GetVisualChild<T>(v); 
      } 
      if (child != null) 
      { 
       break; 
      } 
     } 
     return child; 
    } 
+0

雖然這段代碼可能會回答這個問題,但最好解釋它如何解決問題而不介紹其他人以及爲什麼使用它。從長遠來看,僅有代碼的答案是沒有用的。 – JAL 2015-11-18 03:01:15

+0

對不起,我對這個想法很陌生,代碼是用選擇的變量名自我記錄的。 – 2015-11-20 00:14:47

相關問題