Reputation: 1
I'm coding WPF Program that shows DataTable by binding to DataGrid's ItemsSource property.
And I set following DataGrid's properties in order to select multiple cells.
SelectionMode="Extended"
SelectionUnit="CellOrRowHeader"
Furthermore, I want to add a handler in code behind that sets value to DataGrid's SelectedCells property and change "Anchor" cell (I mean, Anchor cell is only cell that is always contained in SelectedCells during selecting other cells with Shift Key down).
But I don't know how to access Anchor cell's information programmatically.
Please give me advice. Thanks for your help.
Upvotes: 0
Views: 209
Reputation: 1410
I realise that this question is a little old now, however hopefully this information will help someone.
As far as I can tell, there is no public API available for DataGrid
that will allow the reading of the selection anchor, nor the setting of the selection anchor without clearing the existing selection.
To work around this, I had a look at WPF's source code (this for .NET Framework 4.8, this for .NET (previously named .NET Core) at the time of writing) and identified that the selection anchor appears to be solely handled by a field of type Nullable<DataGridCellInfo>
called _selectionAnchor
.
For anyone who has worked with adjusting DataGrid
selection programmatically, you just need to set _selectionAnchor
after the operation for subsequent SHIFT selection operations to behave properly.
If you wish to clear the selection anchor having just programmatically deselected all cells, just set the selection anchor to null
.
You can find more information on reflection here.
_selectionAnchor
field// These lines of code are not intended to do anything more than demonstrate usage of reflection to get and set this private field.
// In reality you'd be passing SetValue() something other than the value the field was already set to.
var fieldInfo = typeof(DataGrid).GetField("_selectionAnchor", BindingFlags.Instance | BindingFlags.NonPublic);
var anchorCellInfo = fieldInfo.GetValue(dataGridInstance) as DataGridCellInfo?;
fieldInfo.SetValue(dataGridInstance, anchorCellInfo);
NOTE: Using reflection to access private/internal functionality always carries the risk that the maintainer of the thing you're accessing could update those private/internal parts at any point in a future release without prior warning. That said, from what I can see, this particular functionality has been pretty much unchanged for years in WPF so you should hopefully be alright.
To be on the safe side, you could potentially add unit tests to verify that the private/internal functionality you're accessing continues to exist and behave in the same way you need it to, so that your application does not subtly break at runtime after updating a package on which you're using reflection to access private/internal functionality.
I should emphasise that it is unusual for a project's unit tests to test functionality in its dependencies, however this seems to me to be a somewhat unique case.
Upvotes: 1