2012-02-27 37 views
3

の.Net 4 WPFのDataGrid MVVMWPFデータグリッドに新しい行にセルを集中する方法

ユーザーがクリックはのviewmodel上でコマンドをトリガボタンを追加します。 viewmodelコマンドexecuteで、グリッドがバインドされているviewmodelのviewcollectionに新しいオブジェクトを追加します。新しい行がグリッドに表示されます。しかし、私はまた、その新しい行の最初の編集可能なセルにフォーカスを送りたいと思います。

私はさらに「mated」mvvmで、新しい行をいつフォーカスするかを知るために、ビューが聴いているビューモデルにイベントを追加しました。

私は検索しましたが、運はありません。私はこの出くわしたとき、私は希望に満ちた:

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

につながるしかし、他の人が報告していると誰も答えなかった問題は、仮想化行動に対処する方法である

Datagrid Set focus on newly added row

グリッドの新しく追加された行はまだ作成されていません。そのため、GetCellsの呼び出しは頻繁に失敗します。また、ScrollIntoViewが必要な場合は、失敗する可能性がさらに高くなります。

私は、運行なしのLoadingRowとRequestBringIntoViewを含む1トンのイベントに夢中になりました。私がフックするイベントに応じて、私はそのセルへの参照を取得することができました。しかし、 "コンテンツの生成が進行中のときにStartAtを呼び出せません"というエラーが表示されます。しかし、私はItemContainerGeneratorの状態をチェックして、セルのBeginEditを呼び出したときにContainersGeneratedでした。ここで

答えて

1

は、プログラムで特定のセルにフォーカスを設定するための一つの方法である:

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

getcellを(の詳細については、次のarticleを参照してください)。

+1

???あなたは私の質問を読みましたか?私はすでにそのページへのリンクを含んでいて、GetCellの問題は、セルがまだ作成されていないと動作しないということです。 – happyfirst

+0

ScrollIntoViewの前にdg.UpdateLayout()を呼び出そうとします –

+0

それは動作します!!!!私は以前、関数呼び出し、優先度の標準を "ディスパッチ"しなければならない修正を発見しました。しかし、これまでのところ、ScrollIntoViewが信頼できると思われる前にUpdateLayoutを呼び出すと、ありがとう! – happyfirst

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

+0

申し訳ありません私はこの考え方に非常に新しいです。 –

関連する問題