2012-02-27 8 views
3

.Net 4 WPF DataGrid MVVMКак сосредоточиться на ячейку новой строки в WPF DataGrid

пользователь нажимает кнопку, которая запускает команду на ViewModel добавить. В команде viewmodel execute, я добавляю новый объект в viewcollection viewmodel, к которому привязана сетка. Новая строка появляется в моей сетке. Однако я также хочу отправить фокус на первую редактируемую ячейку в этой новой строке.

Я даже «обманул» 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, то это намного больше шансов потерпеть неудачу.

Я подключил массу событий, включая LoadRow и RequestBringIntoView, без везения. В зависимости от того, какое событие я зацепил, мне удалось получить ссылку на ячейку. Но потом я получаю сообщение об ошибке «Не могу вызвать StartAt, когда выполняется генерация контента». Но я проверил статус ItemContainerGenerator, и это было ContainersGenerated, когда я сделал звонок на BeginEdit ячейки.

ответ

1

Вот один из способов установить фокус на определенную ячейку программно:

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

Пожалуйста, обратитесь к следующей article для получения дополнительной информации о GetCell().

+1

??? Вы даже прочитали мой вопрос ??? Я уже включил ссылку на эту страницу, и проблема с GetCell заключается в том, что она НЕ работает, если ячейка еще не создана. – happyfirst

+0

попробуйте вызвать dg.UpdateLayout() до ScrollIntoView –

+0

Это работает !!!! Раньше я нашел исправление, где мне пришлось «отправить» вызов функции, приоритет нормальный, и это сработало. Но до сих пор вызов UpdateLayout перед ScrollIntoView казался надежным. Благодаря! – 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

Извините, что я очень новичок в этой мысли, что код сам документировал с выбранными именами переменных. –

Смежные вопросы