How can set focus on particular cell of datagrid in WPF?

Answered How can set focus on particular cell of datagrid in WPF?

  • Monday, May 07, 2012 10:10 AM
     
     

    I need programmatically set focus on particular cell of datagrid in WPF. How it is possible?

    I am using visual studio 2008 .net framework 3.5.

All Replies

  • Monday, May 07, 2012 11:01 AM
     
     
    DataGridCell cell = GetCell(rowIndex, colIndex);
    cell.Focus;

    JP Cowboy Coders Unite!

  • Monday, May 07, 2012 11:02 AM
     
     

    public

    DataGridCell GetCell(int row, int column)
    {
        DataGridRow rowContainer = GetRow(row);

        if
    (rowContainer != null)
        {
            DataGridCellsPresenter presenter = GetVisualChild<DataGridCellsPresenter>(rowContainer);

            // try to get the cell but it may possibly be virtualized
            DataGridCell cell = (DataGridCell)presenter.ItemContainerGenerator.ContainerFromIndex(column);
            if (cell == null)
            {
                // now try to bring into view and retreive the cell
                DataGrid_Standard.ScrollIntoView(rowContainer, DataGrid_Standard.Columns[column]);
                cell = (
    DataGridCell)presenter.ItemContainerGenerator.ContainerFromIndex(column);
            }
            return cell;
        }
        return null;
    }


    JP Cowboy Coders Unite!

  • Monday, May 07, 2012 11:03 AM
     
      Has Code

    Hi,

    you need to know the column and rowindex of the cell in question then just do this -

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


  • Monday, May 07, 2012 11:04 AM
     
      Has Code

    sorry forgot the getcell method - 

    public DataGridCell GetCell(int row, int column)
    {
        DataGridRow rowContainer = GetRow(row);
    
        if (rowContainer != null)
        {
            DataGridCellsPresenter presenter = GetVisualChild<DataGridCellsPresenter>(rowContainer);
    
            // try to get the cell but it may possibly be virtualized
            DataGridCell cell = (DataGridCell)presenter.ItemContainerGenerator.ContainerFromIndex(column);
            if (cell == null)
            {
                // now try to bring into view and retreive the cell
                DataGrid_Standard.ScrollIntoView(rowContainer, DataGrid_Standard.Columns[column]);
                cell = (DataGridCell)presenter.ItemContainerGenerator.ContainerFromIndex(column);
            }
            return cell;
        }
        return null;
    }

    I did this once before using this thread - 

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

  • Monday, May 07, 2012 11:10 AM
     
     

    "DataGridCellsPresenter " class is not available in .net framework 3.5.

    Is there any other solution?

  • Monday, May 07, 2012 11:35 AM
     
     
    Sorry, I found it. will try...
  • Monday, May 07, 2012 11:55 AM
     
      Has Code

    Sorry not working.

    GetVisualChild<DataGridCellsPresenter>(rowContainer);

    This line is creating problem. Because of my datagrid's columns does not created by xaml. I am using C# to all grid process.

  • Wednesday, May 09, 2012 8:29 AM
    Moderator
     
      Has Code

    Hi Rana76,

    Try below code:

     private void button1_Click(object sender, RoutedEventArgs e)
            {
                int index = 3;
                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));
            }
    If it works for you, please mark this as "Answer", if you have any additional questions, please feel free to let me know.

    Have a nice day.


    Annabella Luo[MSFT]
    MSDN Community Support | Feedback to us

  • Monday, May 14, 2012 4:58 AM
     
     

    Hi Annabella Luo,

    I am already using this code to focus on particular row.

    But the problem is that I also want to focus on particular row's particular cell.

    how is it possible?

  • Monday, May 14, 2012 7:29 AM
    Moderator
     
     Answered Has Code

    Hi Rana,

    In my above code you can set focus to particular cell, but in this way, you can set the SelectionUnit of datagrid as Cell.

    So I think another way you can achieve you goal, you can first get the cell from datagrid by using VisualTreehelper, then to set focus on it.

    You can refer to FQA: http://social.msdn.microsoft.com/Forums/en-US/wpf/thread/d3d6b7ec-71f9-4011-afc5-0bf3956e6d78

    DataGridRow rowContainer = (DataGridRow)dataGrid1.ItemContainerGenerator.ContainerFromIndex(rowIndex); 
    DataGridCellsPresenter presenter = GetVisualChild(rowContainer); 
    DataGridCell cell = (DataGridCell)presenter.ItemContainerGenerator.ContainerFromIndex(columnIndex); 
    
    // ...
    
    public 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(v); 
        else
          break; 
      } 
    
      return child; 
    }

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

    Hope it helps.

    Have a nice day.


    Annabella Luo[MSFT]
    MSDN Community Support | Feedback to us

    • Marked As Answer by Rana76 Monday, May 14, 2012 7:49 AM
    •  
  • Thursday, May 17, 2012 3:41 PM
     
     

    Hi,

    I have been trying to use the code above to be able to setfocus to a cell in my datagrid.  I need to do this because I have a grid on multiple tab-panels.  When I select a different tab, I need to select the appropriate cell and set its focus.  I have the cell selection working, but what happens is that the first row/column always gets the focus.  So you have a grid that has a cell selected (highlighted in blue), but the row=0, column=1 cell has the focus so it has a thicker border than the other cells.  I need that behavior to go away.  When I attempt to set focus to the cell using the code above, the following line throws an error:

    DataGridCell cell = (DataGridCell)presenter.ItemContainerGenerator.ContainerFromIndex(columnIndex);

    When I investigate this further, the previous line in the code,

    DataGridCellsPresenter presenter = GetVisualChild(rowContainer); returns a NULL as the presenter.  The rowContainer looks like it is correct though.

    Here is a portion of my XAML that creates the tabs/grids:

         <Grid Height="auto">
      
                <TabControl  Height="auto" Name="myTabControl" SelectedIndex="{Binding Path=SelectedIndex}" SelectionChanged="myTabcontrol_SelectionChanged"
                        ItemsSource="{Binding RegisterFunctionMapViewModel.Pages}"
                        SourceUpdated="myTabControl_SourceUpdated"
                        >
                <!-- DataContent is set to RegisterFunctionPageViewModel -->
                <TabControl.ItemTemplate>
                    <DataTemplate>
                        <WrapPanel >
                            <TextBlock Text="{Binding PageName}" />
                        </WrapPanel>
                    </DataTemplate>

                </TabControl.ItemTemplate>
                <TabControl.ContentTemplate>
                    <DataTemplate>

                        <Grid Width="Auto" Height="Auto">
     
                            <DataGrid x:Name="myDataGrid" FrozenColumnCount="1"  ItemsSource="{Binding Path=Registers}"
                              AutoGenerateColumns="False" FontFamily="MS Reference Sans Serif"
                              FontSize="10"  SelectionUnit="Cell" CanUserAddRows="False" CanUserDeleteRows="False"
                              CanUserReorderColumns="False" CanUserResizeColumns="False" CanUserResizeRows="False"
                              CanUserSortColumns="False" SelectionMode="Single" IsReadOnly="True" Height="Auto"
                              vw:Commands.DataGridDoubleClickCommand  ="{Binding DoubleClickCommand}"
                              SelectedCellsChanged="myDataGrid_SelectedCellsChanged"
                            
                             LoadingRow="myDataGrid_LoadingRow"
                             Initialized="myDataGrid_Initialized"
                                      DataContextChanged="myDataGrid_DataContextChanged"
                              Loaded="myDataGrid_Loaded" IsSynchronizedWithCurrentItem="True">
                               
                                    <DataGrid.Columns>
                                    <DataGridTemplateColumn Header="Register" MinWidth="30"  IsReadOnly="True" CellStyle="{StaticResource NotSelectableColumStyle}" >
                                        <DataGridTemplateColumn.CellTemplate>

                                            <DataTemplate >
                                               
                                                <ListView   Background="LightGray" IsManipulationEnabled="False" >
                                                    <TextBlock Text=""  HorizontalAlignment="Center" IsManipulationEnabled="False" />
                                                    <TextBlock Text="{Binding Path=RegisterIndex}" HorizontalAlignment="Center" IsManipulationEnabled="False" />
                                                </ListView>
                                        </DataTemplate>
                                    </DataGridTemplateColumn.CellTemplate>
                                </DataGridTemplateColumn>
                                    <DataGridTemplateColumn Header="          Bit 15         " MinWidth="50" >
                                    <DataGridTemplateColumn.CellTemplate>
                                        <DataTemplate>
                                               
                                                <StackPanel IsEnabled="{Binding Path=Bit15IsEnabled}"  >
                                                   
                                                    <TextBlock Text="{Binding Path=Bit15Function}" HorizontalAlignment="Center"
                                                               Style="{StaticResource DisabledTextBlock}" IsEnabled="{Binding Path=Bit15IsEnabled}"/>

                                                    <TextBlock Text="{Binding Path=Bit15Value, Converter={StaticResource BoolToStringConverter}}" HorizontalAlignment="Center"
                                                        Style="{StaticResource DisabledTextBlock}" IsEnabled="{Binding Path=Bit15IsEnabled}" />

                                                </StackPanel>

                                            </DataTemplate>
                                    </DataGridTemplateColumn.CellTemplate>
                                
                                </DataGridTemplateColumn>
                                <DataGridTemplateColumn Header="          Bit 14         " MinWidth="50">
                                    <DataGridTemplateColumn.CellTemplate>
                                        <DataTemplate >
                                                <StackPanel IsEnabled="{Binding Path=Bit14IsEnabled}">
                                                    <TextBlock Text="{Binding Path=Bit14Function}" HorizontalAlignment="Center"
                                                               Style="{StaticResource DisabledTextBlock}" IsEnabled="{Binding Path=Bit14IsEnabled}"/>
                                                    <TextBlock Text="{Binding Path=Bit14Value, Converter={StaticResource BoolToStringConverter}}" HorizontalAlignment="Center"
                                                               Style="{StaticResource DisabledTextBlock}" IsEnabled="{Binding Path=Bit14IsEnabled}"/>
                                                </StackPanel>
                                            </DataTemplate>
                                    </DataGridTemplateColumn.CellTemplate>
                                 
                                </DataGridTemplateColumn>
                                <DataGridTemplateColumn Header="          Bit 13         " MinWidth="50">
                                    <DataGridTemplateColumn.CellTemplate>
                                        <DataTemplate>
                                                <StackPanel IsEnabled="{Binding Path=Bit13IsEnabled}">
                                                <TextBlock Text="{Binding Path=Bit13Function}" HorizontalAlignment="Center"
                                                           Style="{StaticResource DisabledTextBlock}" IsEnabled="{Binding Path=Bit13IsEnabled}"/>
                                                <TextBlock Text="{Binding Path=Bit13Value, Converter={StaticResource BoolToStringConverter}}" HorizontalAlignment="Center"
                                                           Style="{StaticResource DisabledTextBlock}" IsEnabled="{Binding Path=Bit13IsEnabled}"/>
                                            </StackPanel>
                                        </DataTemplate>
                                    </DataGridTemplateColumn.CellTemplate>
                                  
                                </DataGridTemplateColumn>

    So I'm not sure what is wrong here.

     


    Al