Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do you make the WPF Datagrid select a cell when you first tab into it

Tags:

People also ask

How do I select a cell in DataGrid?

You can get the selected cells, rows, or columns from a DataGridView control by using the corresponding properties: SelectedCells, SelectedRows, and SelectedColumns.

How to select row in DataGrid wpf?

WPF DataGrid (SfDataGrid) allows you to select one or more rows or cells. For selecting specific row or group of rows you have to set SelectionUnit as Row and for selecting a specific cell or group of cells you have to set SelectionUnit as Cell or Any. In SelectionUnit.

Can user add rows DataGrid WPF?

WPF DataGrid (SfDataGrid) provides built-in row called AddNewRow. It allows user to add a new row to underlying collection. You can enable or disable by setting SfDataGrid.

What is DataGridView in WPF?

A DataGrid is a control that displays data in a customizable grid. It provides a flexible way to display a collection of data in rows and columns. The hierarchical inheritance of DataGrid class is as follows −


When I tab into the WPF Datagrid it focuses the first cell (with a rectangle) but does not select it (in blue). If I press tab again it focuses and selects it.

I think the DataGridCell actually has IsSelected=true, but it is not being painted in blue. I have tried hacking around with the datagrid and visual-states but I can't make it repaint the grid correctly when you first tab in.

Has anyone seen this before and do you have a solution?

code to reproduce:

MainWindow.xaml

<Window x:Class="WpfApplication1.MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    Title="MainWindow" Height="350" Width="525">
    <StackPanel>
        <TextBox Width="100"/>
        <DataGrid SelectionMode="Single" SelectionUnit="Cell"
              ItemsSource="{Binding MyItems}" AutoGenerateColumns="True"/>
    </StackPanel>
</Window>

MainWindow.xaml.cs

using System.Collections.Generic;
using System.Windows;

namespace WpfApplication1
{
    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();

            MyItems.Add(new Thingy() { Name = "Frank", Age = 34 });
            MyItems.Add(new Thingy() { Name = "Jim", Age = 43 });
            MyItems.Add(new Thingy() { Name = "Bob", Age = 56 });
            MyItems.Add(new Thingy() { Name = "Harry", Age = 23 });

            DataContext = this;
        }

        private List<Thingy> _myItems = new List<Thingy>();
        public List<Thingy> MyItems
        {
            get { return _myItems; }
        }
    }

    public class Thingy
    {
        public string Name { get; set; }
        public int Age { get; set; }
    }
}

click on the TextBox, then hit tab --- cell 1 is not selected

hit tab again --- cell 2 is selected

Any help is much appreciated, thanks.

Update:

When SelectionUnit=FullRow, I have had some success along the lines shown below, if SelectedIndex is set to 0 upon creation the first row is now selected in blue. It still needs some work to cope with shift-tab etc. There is still a problem though because when I change the SelectionMode to extended and press shift-downarrow the second row gets selected but the first row gets unselected (they should both be selected). If I do it again rows 2+3 are selected which is correct and it continues to work ok after that.

protected override void OnIsKeyboardFocusWithinChanged(DependencyPropertyChangedEventArgs e)
    {
        base.OnIsKeyboardFocusWithinChanged(e);

        int oldIdx = this.SelectedIndex;
        this.SelectedIndex = -1;
        this.SelectedIndex = oldIdx;
    }

Further Update:

Fixed that issue by setting the private _selectionAnchor field. (Thanks ILSpy)

 protected override void OnIsKeyboardFocusWithinChanged(DependencyPropertyChangedEventArgs e)
    {
        base.OnIsKeyboardFocusWithinChanged(e);

        this.SelectedIndex = -1;
        this.SelectedIndex = 0;

        SelectionAnchor = SelectedCells[0];
    }

    protected DataGridCellInfo? SelectionAnchor
    {
        get
        {
            return typeof(DataGrid).GetField("_selectionAnchor", BindingFlags.Instance | BindingFlags.NonPublic).GetValue(this) as DataGridCellInfo?;
        }
        set
        {
            typeof(DataGrid).GetField("_selectionAnchor", BindingFlags.Instance | BindingFlags.NonPublic).SetValue(this, value);
        }
    }