5
votes

I Have a DataGrid with some data loaded. I need to set focus in the first row of this grid.

I will call this method from a button onClick event.

The myGrid.Focus() does not focus the rows inside the grid.

4

4 Answers

4
votes

It is one of the hardest job in WPF, and reason is because of Virtualization and the fact that UI Render thread is different from the thread that runs our code (you can not find when exactly UI render finished). for a complete reference you can have look here http://social.technet.microsoft.com/wiki/contents/articles/21202.wpf-programmatically-selecting-and-focusing-a-row-or-cell-in-a-datagrid.aspx

using Dispatcher.Invoke might works for some situations (believe me in WPF Dispatcher.Invoke is your best friend and biggest enemy)

dgGrid.ItemsSource = new List<object>() { new { I = 10, J = 20 }, new { I = 10, J = 20 }, new { I = 10, J = 20 }, new { I = 10, J = 20 }, new { I = 10, J = 20 } };
        Dispatcher.Invoke(new Action(delegate()
        {
            grd.SelectedIndex = 0;
            grd.Focus();
        }
    ), System.Windows.Threading.DispatcherPriority.Background);

or robustest one from linked article

public static DataGridCell GetCell(DataGrid dataGrid, DataGridRow rowContainer, int column)
{
    if (rowContainer != null)
    {
        DataGridCellsPresenter presenter = FindVisualChild<DataGridCellsPresenter>(rowContainer);
        if (presenter == null)
        {
            /* if the row has been virtualized away, call its ApplyTemplate() method
             * to build its visual tree in order for the DataGridCellsPresenter
             * and the DataGridCells to be created */
            rowContainer.ApplyTemplate();
            presenter = FindVisualChild<DataGridCellsPresenter>(rowContainer);
        }
        if (presenter != null)
        {
            DataGridCell cell = presenter.ItemContainerGenerator.ContainerFromIndex(column) as DataGridCell;
            if (cell == null)
            {
                /* bring the column into view
                 * in case it has been virtualized away */
                dataGrid.ScrollIntoView(rowContainer, dataGrid.Columns[column]);
                cell = presenter.ItemContainerGenerator.ContainerFromIndex(column) as DataGridCell;
            }
            return cell;
        }
    }
    return null;
}

  public static void SelectRowByIndex(DataGrid dataGrid, int rowIndex)
    {
        if (!dataGrid.SelectionUnit.Equals(DataGridSelectionUnit.FullRow))
            throw new ArgumentException("The SelectionUnit of the DataGrid must be set to FullRow.");

        if (rowIndex < 0 || rowIndex > (dataGrid.Items.Count - 1))
            throw new ArgumentException(string.Format("{0} is an invalid row index.", rowIndex));

        dataGrid.SelectedItems.Clear();
        /* set the SelectedItem property */
        object item = dataGrid.Items[rowIndex]; // = Product X
        dataGrid.SelectedItem = item;

        DataGridRow row = dataGrid.ItemContainerGenerator.ContainerFromIndex(rowIndex) as DataGridRow;
        if (row == null)
        {
            /* bring the data item (Product object) into view
             * in case it has been virtualized away */
            dataGrid.ScrollIntoView(item);
            row = dataGrid.ItemContainerGenerator.ContainerFromIndex(rowIndex) as DataGridRow;
        }
         if (row != null)
    {
        DataGridCell cell = GetCell(dataGrid, row, 0);
        if(cell != null)
            cell.Focus();
    }
 }

you need to add these static methods call the second one it first tries tries find (or draw the row if it is draw yet then set focus on it).

1
votes

Try this:

if (e.Key == Key.Up || e.Key == Key.Down) 
{ 
    var uiElement = e.OriginalSource as UIElement; 
    dgvRoute.Focus(); //Datagrid 
    uiElement.MoveFocus(new TraversalRequest(FocusNavigationDirection.Next));
}
-2
votes
mygrid.SelectedItem = mygrid.Items.Count > 0 ? mygrid.Items[0] : null;
-3
votes

If you want to focus first value in grid try following

myGrid.SelectedIndex = 0;