Sayak Banerjee
Sayak Banerjee

Reputation: 1964

Focusing data grid cell when focus is within

I have a datagrid which has IsTabStop set to false for the DataGridCell style. This was done to avoid focusing on every datagrid cell when pressing tab.

Now, I am able to focus on hyperlinks and radio buttons by pressing tab, but the row doesn't get selected when I do so. I have tried the following code:

<Style TargetType="{x:Type DataGridCell}">
    <Style.Triggers>
        <Trigger Property="IsKeyboardFocusWithin" Value="True">
            <Setter Property="IsSelected" Value="True" />
        </Trigger>
    </Style.Triggers>
</Style>

Although, seemingly, this code has no effect. Please suggest any possible workarounds.

Upvotes: 0

Views: 5671

Answers (1)

Natxo
Natxo

Reputation: 2947

You should use the SelectedItem property of the datagrid. Of course, check that SelectionUnit is not set to "cell"

Try this:

<Style TargetType="{x:Type DataGridCell}">
    <EventSetter Event="GotFocus" Handler="DataGridCell_GotFocus"></EventSetter>
</Style>

If myDatagrid is the name of your Datagrid:

private void DataGridCell_GotFocus(object sender, EventArgs e)
{
    DataGridCell cell = sender as DataGridCell;
    myDatagrid.SelectedItem = cell.DataContext;
}

EDIT:

If you need a something more reusable, i suggest using attached behaviours. In this case i would create an attached behaviour to be used in the datagrid itself:

<Style TargetType="{x:Type DataGrid}">
    <Setter Property="views:MyBehaviours.IsCellRowSelected" Value="true"></Setter>
</Style>

This is the code, it will monitor changes on the SelectedCellsChanged event of the datagrid:

public static class MyBehaviours
{
    public static bool GetIsCellRowSelected(DependencyObject obj)
    {
        return (bool)obj.GetValue(IsCellRowSelectedProperty);
    }

    public static void SetIsCellRowSelected(DependencyObject obj, bool value)
    {
        obj.SetValue(IsCellRowSelectedProperty, value);
    }

    public static readonly DependencyProperty IsCellRowSelectedProperty =
      DependencyProperty.RegisterAttached("IsCellRowSelected",
      typeof(bool), typeof(MyBehaviours),
      new UIPropertyMetadata(false, OnIsCellRowSelected));

    static void OnIsCellRowSelected(DependencyObject depObj, DependencyPropertyChangedEventArgs e)
    {
        DataGrid item = depObj as DataGrid;
        if (item == null)
            return;

        if (e.NewValue is bool == false)
            return;

        if ((bool)e.NewValue)
            item.SelectedCellsChanged += SelectRow;
        else
            item.SelectedCellsChanged -= SelectRow;
    }

    static void SelectRow(object sender, SelectedCellsChangedEventArgs e)
    {
        if (e.AddedCells.Count > 0)
        {
            DataGrid dg = sender as DataGrid;
            var cell = e.AddedCells.Last();
            dg.SelectedItem = cell.Item;
        }
    }
}

In case of multiple cell selection, last cell's row will be selected. You may modify this to suit your needs.

Upvotes: 1

Related Questions