1

When I create a DataGrid, by default, to select a row, I need to click on the control inside the cell.

I want to select the row wherever I click in the row.

Is there a way to do that?

<DataGrid AutoGenerateColumns="False"
      CanUserAddRows="False" 
      IsReadOnly="True"
      Style="{StaticResource DataGridStyle}"
      HorizontalContentAlignment ="Center"
      VerticalContentAlignment ="Center"
      VerticalScrollBarVisibility="Auto"
      SelectionMode="Single"
      ItemsSource="{Binding Items, Mode=OneWay}"
      SelectedItem="{Binding SelectedItem, Mode=TwoWay}">
<DataGrid.Columns>
    <DataGridTextColumn Header="Name"
                        Binding="{Binding Name}"
                        Width="4*" />
    <DataGridTextColumn Header="Description"
                        Binding="{Binding Description}"
                        Width="4*" />
</DataGrid.Columns>

Ayman
  • 580
  • 9
  • 27
G.Dealmeida
  • 325
  • 3
  • 14

1 Answers1

2

if you want to select row even if you won't click on the particular cell you should add ItemContainerStyle with EventSetter for the DataGridRow as follows:

<Grid>
    <DataGrid AutoGenerateColumns="False" ItemsSource="{Binding Customers}">
        <DataGrid.Columns>
            <DataGridTextColumn Header="Name" Binding="{Binding Name}" />
            <DataGridTextColumn Header="Name" Binding="{Binding Surname}" />
            <DataGridTextColumn Header="Name" Binding="{Binding Age}" />
        </DataGrid.Columns>
        <DataGrid.ItemContainerStyle>
            <Style TargetType="{x:Type DataGridRow}">
                <EventSetter Event="MouseDown" Handler="DataGridRow_MouseDown" />
            </Style>
        </DataGrid.ItemContainerStyle>
    </DataGrid>
</Grid>

and in the code-behind you might obtain datarowgrid from sender, iterate through the visual tree in order to obtain datagrid itself (if you don't want to call it by x:name for example), and then simply set SelectedItem as dataGridrow.Item

    private void DataGridRow_MouseDown(object sender, System.Windows.Input.MouseButtonEventArgs e)
    {
        var dataGridRow = (DataGridRow)sender;
        if (dataGridRow != null)
        {
            var dataGridRowParent = FindParent<DataGrid>(dataGridRow);
            if (dataGridRowParent != null)
            {
                dataGridRowParent.SelectedItem = dataGridRow.Item;
            }
        }
    }

    public static T FindParent<T>(DependencyObject child) where T : DependencyObject
    {
        //get parent item
        DependencyObject parentObject = VisualTreeHelper.GetParent(child);

        //we've reached the end of the tree
        if (parentObject == null) return null;

        //check if the parent matches the type we're looking for
        T parent = parentObject as T;
        if (parent != null)
            return parent;
        else
            return FindParent<T>(parentObject);
    }
pjrki
  • 248
  • 1
  • 3
  • 15
  • Thank you, this does answer the question but I like to have a clean .xaml.cs. So I decided to remove DataGridTextColumn and replace it with a DataGridTemplate with a TextBox inside. By changing size, Margin and Alignment properties, I can manage an "illusion" or RowSelection with no code in .xaml.cs – G.Dealmeida Oct 29 '18 at 14:12
  • Hi there, you're welcome sir. I was wondering about setting up commands for the eventsetters through a custom behavior or something called iteractions but changing these basic properties is actually a faster solution. Regards. – pjrki Oct 29 '18 at 14:31