Lets assume that the view is the following:
<Window x:Class="RadGridViewSelectionBug.MainWindow" xmlns:local="clr-namespace:RadGridViewSelectionBug" xmlns:telerik="http://schemas.telerik.com/2008/xaml/presentation" mc:Ignorable="d" Title="MainWindow" Height="350" Width="525" WindowState="Maximized"> <Grid> <Grid.RowDefinitions> <RowDefinition Height="Auto"/> <RowDefinition /> </Grid.RowDefinitions> <Button HorizontalAlignment="Left" Click="Button_Click">Click Me</Button> <telerik:RadGridView x:Name="radGridView" Grid.Row="1" NewRowPosition="None" RowIndicatorVisibility="Collapsed" ItemsSource="{Binding DataView}" ShowGroupPanel="False" AutoGenerateColumns="True" IsReadOnly="True" IsFilteringAllowed="False" EnableColumnVirtualization="True" CanUserSortColumns="False" CanUserDeleteRows="False" CanUserInsertRows="False" SelectionMode="Extended" SelectionUnit="Cell" MinColumnWidth="50" CanUserReorderColumns="False" CanUserFreezeColumns="False" GroupRenderMode="Flat" ValidatesOnDataErrors="None" ColumnWidth="75" FrozenColumnCount="1" FrozenColumnsSplitterVisibility="Collapsed" ClipboardCopyMode="Cells" ClipboardPasteMode="Cells" TextBlock.TextAlignment="Center"> </telerik:RadGridView> </Grid></Window>
The Code behind is the following:
public partial class MainWindow : Window{ public MainWindow() { InitializeComponent(); this.DataContext = new MainViewModel(); radGridView.SelectedCellsChanged += RadGridView_SelectedCellsChanged; } private void RadGridView_SelectedCellsChanged(object sender, Telerik.Windows.Controls.GridView.GridViewSelectedCellsChangedEventArgs e) { var selectedCells = (sender as RadGridView).SelectedCells.Where(c => c != null).ToList(); if (selectedCells.Any()) { var firstCell = selectedCells.First(); var lastCell = selectedCells.Last(); int fromRowIndex = firstCell.Column.DataControl.Items.IndexOf(firstCell.Item); int fromColIndex = firstCell.Column.DisplayIndex; int toRowIndex = lastCell.Column.DataControl.Items.IndexOf(lastCell.Item); int toColIndex = lastCell.Column.DisplayIndex; Console.WriteLine(string.Format("{0}, {1}, {2}, {3}", fromRowIndex, fromColIndex, toRowIndex, toColIndex)); } } private void Button_Click(object sender, RoutedEventArgs e) { (this.DataContext as MainViewModel).RebuildData(); }}
And the MainViewModel code is:
public class MainViewModel : ViewModelBase{ private DataTable _dataTable; public MainViewModel() { _dataTable = new DataTable(); _dataTable.Columns.Add(new DataColumn() { Caption = "Col1", DataType = typeof(int), }); _dataTable.Columns.Add(new DataColumn() { Caption = "Col2", DataType = typeof(int), }); _dataTable.Columns.Add(new DataColumn() { Caption = "Col3", DataType = typeof(int), }); for (int i = 0; i <100; i++) { var row = _dataTable.NewRow(); for (int j = 0; j < 3; j++) { row[j] = 0; } _dataTable.Rows.Add(row); } } internal void RebuildData() { var dataTable = new DataTable(); dataTable.Columns.Add(new DataColumn() { Caption = "Col1", DataType = typeof(int), }); dataTable.Columns.Add(new DataColumn() { Caption = "Col2", DataType = typeof(int), }); dataTable.Columns.Add(new DataColumn() { Caption = "Col3", DataType = typeof(int), }); for (int i = 0; i < 10; i++) { var row = dataTable.NewRow(); for (int j = 0; j < 3; j++) { row[j] = 0; } dataTable.Rows.Add(row); } DataTable = dataTable; } public DataView DataView { get { return _dataTable.DefaultView; } } public DataTable DataTable { get { return _dataTable; } set { _dataTable = value; OnPropertyChanged("DataView"); } }}
Run the code. Then Press Ctrl + A, in order to select all cells.
Then click on the Button.
You should get an exception (The grid view code tries to access a column with index that does not exist).
If I remove the cellInfo null check, and just write:
var selectedCells = (sender as RadGridView).SelectedCells;
Then I'll get that few cells in the SelectedCells are nulls (I might get that the firstCell, or the lastCell are nulls).
Now for another interesting bug:
Restart the code.
Select the first cell (upper left corner). The code shows Row = 0 and Col = 0 --> Good.
Now Click the button.. The selection is cleared...
Now Select the first cell again. The code shows Row = -1, Col = 0. (WTF?)
Now, any cell that you will select on the first row will give you that result. But if you select a cell from a different row, and then reselect a cell from the first row, then the problem is fixed.
Btw, getting the Item from the Added cells and checking its row index does give the correct result, but what I'm trying to do is to have the user have only 1 selected region (A rectangle of selected cells), so I can have a from row, from cell, to row, and to cell information.
So, in my code, I also clear selection in Grid PreviewMouseLeftButtonDown.
Any other suggestions of having only rectangular selection will be welcome (since right now, clicking on blank area, or clicking the scrollbar also clears the selection).
Furthermore, any suggestions on how to get the correct selected region will be welcome.
Thanks