To reproduce: public Form1() { InitializeComponent(); this.radGridView1.ReadOnly = true; this.radGridView1.MasterTemplate.AutoSizeColumnsMode = GridViewAutoSizeColumnsMode.Fill; this.radGridView1.DataSource = CreateDataSource(); this.radGridView1.Relations.AddSelfReference(this.radGridView1.MasterTemplate, "ID", "ParentID"); this.radGridView1.Columns["ID"].IsVisible = false; this.radGridView1.Columns["ParentID"].IsVisible = false; this.radGridView1.MultiSelect = true; this.radGridView1.SelectionMode = GridViewSelectionMode.CellSelect; } private static DataTable CreateDataSource() { DataTable dataSource = new DataTable("fileSystem"); dataSource.Columns.Add("ID", typeof(int)); dataSource.Columns.Add("ParentID", typeof(int)); dataSource.Columns.Add("Name", typeof(string)); dataSource.Columns.Add("Date", typeof(DateTime)); dataSource.Columns.Add("Type", typeof(string)); dataSource.Columns.Add("Size", typeof(int)); dataSource.Rows.Add(1, null, "Program Files", DateTime.Now.AddDays(-100), "Folder", 5120); dataSource.Rows.Add(2, 1, "Visual Studio 2010", DateTime.Now.AddDays(-100), "Folder", 3220); dataSource.Rows.Add(3, 2, "bin", DateTime.Now.AddDays(-100), "Folder", 3220); dataSource.Rows.Add(4, 2, "READEME.txt", DateTime.Now.AddDays(-100), "Text Document", 3); dataSource.Rows.Add(5, 1, "Telerik RadControls", DateTime.Now.AddDays(-10), "Folder", 3120); dataSource.Rows.Add(6, 5, "Telerik UI for Winforms", DateTime.Now.AddDays(-10), "Folder", 101); dataSource.Rows.Add(7, 5, "Telerik UI for Silverlight", DateTime.Now.AddDays(-10), "Folder", 123); dataSource.Rows.Add(8, 5, "Telerik UI for WPF", DateTime.Now.AddDays(-10), "Folder", 221); dataSource.Rows.Add(9, 5, "Telerik UI for ASP.NET AJAX", DateTime.Now.AddDays(-10), "Folder", 121); dataSource.Rows.Add(10, 1, "Microsoft Office 2010", DateTime.Now.AddDays(-120), "Folder", 1230); dataSource.Rows.Add(11, 10, "Microsoft Word 2010", DateTime.Now.AddDays(-120), "Folder", 1230); dataSource.Rows.Add(12, 10, "Microsoft Excel 2010", DateTime.Now.AddDays(-120), "Folder", 1230); dataSource.Rows.Add(13, 10, "Microsoft Powerpoint 2010", DateTime.Now.AddDays(-120), "Folder", 1230); dataSource.Rows.Add(14, 1, "Debug Diagnostic Tools v1.0", DateTime.Now.AddDays(-400), "Folder", 2120); dataSource.Rows.Add(15, 1, "Designer's 3D Tools", DateTime.Now.AddDays(-500), "Folder", 1120); dataSource.Rows.Add(16, 1, "Communication", DateTime.Now.AddDays(-700), "Folder", 120); dataSource.Rows.Add(17, null, "My Documents", DateTime.Now.AddDays(-200), "Folder", 1024); dataSource.Rows.Add(18, 17, "Salaries.xlsx", DateTime.Now.AddDays(-200), "Excel File", 1); dataSource.Rows.Add(19, 17, "RecessionAnalysis.xlsx", DateTime.Now.AddDays(-200), "Excel File", 1); dataSource.Rows.Add(20, null, "Windows", DateTime.Now.AddDays(-100), "Folder", 10240); dataSource.Rows.Add(21, 20, "System32", DateTime.Now.AddDays(-220), "Folder", 510); dataSource.Rows.Add(22, 20, "assembly", DateTime.Now.AddDays(-20), "Folder", 240); dataSource.Rows.Add(23, 22, "System.Data.dll", DateTime.Now.AddDays(-20), "Assembly File", 4); dataSource.Rows.Add(24, 22, "System.Core.dll", DateTime.Now.AddDays(-20), "Assembly File", 2); dataSource.Rows.Add(25, 22, "System.Drawings.dll", DateTime.Now.AddDays(-20), "Assembly File", 3); dataSource.Rows.Add(26, 22, "Telerik.WinControls.UI.dll", DateTime.Now.AddDays(-20), "Assembly File", 5); dataSource.Rows.Add(27, null, "Users", DateTime.Now.AddDays(-100), "Folder", 5512); dataSource.Rows.Add(28, 27, "Administrator", DateTime.Now.AddDays(-100), "Folder", 1512); dataSource.Rows.Add(29, 27, "Guest", DateTime.Now.AddDays(-100), "Folder", 2512); dataSource.Rows.Add(30, 27, "User1", DateTime.Now.AddDays(-100), "Folder", 3512); dataSource.Rows.Add(31, null, "Share", DateTime.Now.AddDays(-50), "Folder", 15360); dataSource.Rows.Add(32, 31, "Photos", DateTime.Now.AddDays(-50), "Folder", 360); dataSource.Rows.Add(33, 32, "Flowers.JPG", DateTime.Now.AddDays(-50), "JPEG File", 1); dataSource.Rows.Add(34, 32, "Panda.GIF", DateTime.Now.AddDays(-50), "GIF File", 3); dataSource.Rows.Add(35, 32, "Landscape.png", DateTime.Now.AddDays(-50), "PNG File", 4); dataSource.Rows.Add(36, null, "Music", DateTime.Now.AddDays(-2), "Folder", 0); dataSource.Rows.Add(37, 36, "Mozart", DateTime.Now.AddDays(-3), "Folder", 0); dataSource.Rows.Add(38, 36, "Pavarotti", DateTime.Now.AddDays(-40), "Folder", 0); dataSource.Rows.Add(39, 36, "AC/DC", DateTime.Now.AddDays(-50), "Folder", 0); dataSource.Rows.Add(40, 36, "Queen", DateTime.Now.AddDays(-8), "Folder", 0); dataSource.Rows.Add(33, null, "Boot.ini", DateTime.Now.AddDays(-10), "INI File", 0); return dataSource; } Workaround: custom row behavior //replace row behavior for hierarchical rows BaseGridBehavior behavior = (BaseGridBehavior)this.radGridView1.GridBehavior; behavior.UnregisterBehavior(typeof(GridViewHierarchyRowInfo)); behavior.RegisterBehavior(typeof(GridViewHierarchyRowInfo), new MyGridHierarchyRowBehavior()); //replace row behavior for data rows behavior.UnregisterBehavior(typeof(GridViewDataRowInfo)); behavior.RegisterBehavior(typeof(GridViewDataRowInfo), new MyGridDataRowBehavior()); public class MyGridHierarchyRowBehavior : GridHierarchyRowBehavior { protected override bool ProcessMouseSelection(Point mousePosition, GridCellElement currentCell) { if (this.RootGridBehavior.LockedBehavior != this) { this.GridControl.Capture = true; this.RootGridBehavior.LockBehavior(this); } bool result = this.DoMouseSelection(currentCell, mousePosition); return result; } private bool DoMouseSelection(GridCellElement currentCell, Point currentLocation) { if (!this.MasterTemplate.MultiSelect || this.GridViewElement.Template.AllowRowReorder) { return false; } Point mouseDownLocation = (Point)typeof(GridRowBehavior).GetField("mouseDownLocation", BindingFlags.Instance | BindingFlags.NonPublic).GetValue(this); Rectangle rect = new Rectangle(mouseDownLocation.X - SystemInformation.DragSize.Width / 2, mouseDownLocation.Y - SystemInformation.DragSize.Height / 2, SystemInformation.DragSize.Width, SystemInformation.DragSize.Height); if (rect.Contains(currentLocation)) { return false; } GridTableElement tableElement = this.GridViewElement.CurrentView as GridTableElement; if (tableElement == null) { return false; } bool selectionStartedOnAPinnedColumn = (bool)typeof(GridRowBehavior).GetField("selectionStartedOnAPinnedColumn", BindingFlags.Instance | BindingFlags.NonPublic).GetValue(this); bool mouseDownOnLeftPinnedColumn = (bool)typeof(GridRowBehavior).GetField("mouseDownOnLeftPinnedColumn", BindingFlags.Instance | BindingFlags.NonPublic).GetValue(this); bool mouseDownOnRightPinnedColumn = (bool)typeof(GridRowBehavior).GetField("mouseDownOnRightPinnedColumn", BindingFlags.Instance | BindingFlags.NonPublic).GetValue(this); bool selectionStartedOnAPinnedRow = (bool)typeof(GridRowBehavior).GetField("selectionStartedOnAPinnedRow", BindingFlags.Instance | BindingFlags.NonPublic).GetValue(this); bool mouseDownOnTopPinnedRow = (bool)typeof(GridRowBehavior).GetField("mouseDownOnTopPinnedRow", BindingFlags.Instance | BindingFlags.NonPublic).GetValue(this); bool mouseDownOnBottomPinnedRow = (bool)typeof(GridRowBehavior).GetField("mouseDownOnBottomPinnedRow", BindingFlags.Instance | BindingFlags.NonPublic).GetValue(this); if (selectionStartedOnAPinnedColumn && this.GetViewportBounds(tableElement).Contains(currentLocation)) { if (mouseDownOnLeftPinnedColumn) { tableElement.HScrollBar.Value = tableElement.HScrollBar.Minimum; mouseDownOnLeftPinnedColumn = false; } if (mouseDownOnRightPinnedColumn) { tableElement.HScrollBar.Value = tableElement.HScrollBar.Maximum - tableElement.HScrollBar.LargeChange + 1; mouseDownOnRightPinnedColumn = false; } selectionStartedOnAPinnedColumn = false; } if (selectionStartedOnAPinnedRow && this.GetViewportBounds(tableElement).Contains(currentLocation)) { if (mouseDownOnTopPinnedRow) { tableElement.VScrollBar.Value = tableElement.VScrollBar.Minimum; mouseDownOnTopPinnedRow = false; } if (mouseDownOnBottomPinnedRow) { tableElement.VScrollBar.Value = tableElement.VScrollBar.Maximum - tableElement.VScrollBar.LargeChange + 1; mouseDownOnBottomPinnedRow = false; } selectionStartedOnAPinnedRow = false; } if (currentCell.RowInfo is GridViewDataRowInfo) { if (this.MasterTemplate.SelectionMode == GridViewSelectionMode.FullRowSelect) { typeof(GridHierarchyRowBehavior).GetMethod("DoMultiFullRowSelect", BindingFlags.Instance | BindingFlags.NonPublic).Invoke(this, new object[] { currentCell, currentLocation }); } else { this.DoMultiCellSelect(currentCell, currentLocation); } } return true; } private GridRowElement GetFirstScrollableRowElement(GridTableElement tableElement) { if (tableElement.ViewElement.ScrollableRows.Children.Count < 1) { return null; } return (GridRowElement)tableElement.ViewElement.ScrollableRows.Children[0]; } private GridViewColumn GetFirstScrollableColumn(GridTableElement tableElement) { GridRowElement rowElement = this.GetFirstScrollableRowElement(tableElement); if (rowElement == null) { return null; } int counter = 0; while (counter < rowElement.VisualCells.Count) { if (!rowElement.VisualCells[counter].IsPinned && rowElement.VisualCells[counter].ColumnInfo is GridViewDataColumn) { return rowElement.VisualCells[counter].ColumnInfo; } counter++; } return null; } private int GetRowIndex(GridViewRowInfo rowInfo) { List<GridViewRowInfo> orderedRows = typeof(GridRowBehavior).GetField("orderedRows", BindingFlags.NonPublic | BindingFlags.Instance).GetValue(this) as List<GridViewRowInfo>; return orderedRows.IndexOf(rowInfo); } private void DoMultiCellSelect(GridCellElement currentCell, Point currentLocation) { #region GridViewSelection int rowUnderMouseIndex = this.GetRowIndex(this.RootGridBehavior.RowAtPoint.RowInfo); int columnUnderMouseIndex = 0; GridTableElement tableElement = this.GridViewElement.CurrentView as GridTableElement; GridViewColumn col = this.RootGridBehavior.CellAtPoint.ColumnInfo; if (this.RootGridBehavior.CellAtPoint.ColumnInfo is GridViewRowHeaderColumn) { col = this.GetFirstScrollableColumn(tableElement); } List<GridViewRowInfo> orderedRows = typeof(GridRowBehavior).GetField("orderedRows", BindingFlags.NonPublic | BindingFlags.Instance).GetValue(this) as List<GridViewRowInfo>; List<GridViewColumn> orderedColumns = typeof(GridRowBehavior).GetField("orderedColumns", BindingFlags.NonPublic | BindingFlags.Instance).GetValue(this) as List<GridViewColumn>; if (col != null) { columnUnderMouseIndex = orderedColumns.IndexOf(col); } List<GridViewRowInfo> rows = new List<GridViewRowInfo>(); int anchorRowIndex = (int)typeof(GridRowBehavior).GetField("anchorRowIndex", BindingFlags.NonPublic | BindingFlags.Instance).GetValue(this); int startIndex = Math.Min(anchorRowIndex, rowUnderMouseIndex); int endIndex = Math.Max(anchorRowIndex, rowUnderMouseIndex); for (int i = startIndex; i < endIndex; i++) { if (i < 0) { continue; } if (orderedRows.Count > i) { rows.Add(orderedRows[i]); } } int anchorColumnIndex = (int)typeof(GridRowBehavior).GetField("anchorColumnIndex", BindingFlags.NonPublic | BindingFlags.Instance).GetValue(this); int columnLeft = Math.Min(anchorColumnIndex, columnUnderMouseIndex); int columnRight = Math.Max(anchorColumnIndex, columnUnderMouseIndex); GridViewSelectionCancelEventArgs cancelArgs = new GridViewSelectionCancelEventArgs(rows, columnLeft, columnRight); this.MasterTemplate.EventDispatcher.RaiseEvent<GridViewSelectionCancelEventArgs>(EventDispatcher.SelectionChanging, this, cancelArgs); if (cancelArgs.Cancel) { return; } #endregion bool isProcessedShiftOrControl = this.IsPressedShift || this.IsPressedControl; ObservableCollection<GridViewCellInfo> SelectedCells = typeof(GridViewSelectedCellsCollection).GetProperty("ObservableItems", BindingFlags.Instance | BindingFlags.NonPublic).GetValue(this.MasterTemplate.SelectedCells) as ObservableCollection<GridViewCellInfo>; SelectedCells.BeginUpdate(); this.GridViewElement.CurrentView.BeginUpdate(); int count = this.MasterTemplate.SelectedCells.Count; bool notifyUpdates = this.ProcessCellSelection(rowUnderMouseIndex, columnUnderMouseIndex); if (isProcessedShiftOrControl) { notifyUpdates = count != this.MasterTemplate.SelectedCells.Count; } this.GridViewElement.CurrentView.EndUpdate(false); SelectedCells.EndUpdate(notifyUpdates); } private bool ProcessCellSelection(int rowUnderMouseIndex, int columnUnderMouseIndex) { int currentRowIndex = (int)typeof(GridRowBehavior).GetField("currentRowIndex", BindingFlags.NonPublic | BindingFlags.Instance).GetValue(this); int anchorRowIndex = (int)typeof(GridRowBehavior).GetField("anchorRowIndex", BindingFlags.NonPublic | BindingFlags.Instance).GetValue(this); int currentColumnIndex = (int)typeof(GridRowBehavior).GetField("currentColumnIndex", BindingFlags.NonPublic | BindingFlags.Instance).GetValue(this); int anchorColumnIndex = (int)typeof(GridRowBehavior).GetField("anchorColumnIndex", BindingFlags.NonPublic | BindingFlags.Instance).GetValue(this); if ((rowUnderMouseIndex == currentRowIndex && columnUnderMouseIndex == currentColumnIndex) || (rowUnderMouseIndex < 0 || columnUnderMouseIndex < 0)) { return false; } bool verticalDirectionChange = (rowUnderMouseIndex < currentRowIndex && currentRowIndex > anchorRowIndex && rowUnderMouseIndex < anchorRowIndex) || (rowUnderMouseIndex > currentRowIndex && currentRowIndex < anchorRowIndex && rowUnderMouseIndex > anchorRowIndex); bool horizontalDirectionChange = (columnUnderMouseIndex < currentColumnIndex && currentColumnIndex > anchorColumnIndex && columnUnderMouseIndex < anchorColumnIndex) || (columnUnderMouseIndex > currentColumnIndex && currentColumnIndex < anchorColumnIndex && columnUnderMouseIndex > anchorColumnIndex); List<GridViewRowInfo> orderedRows = typeof(GridRowBehavior).GetField("orderedRows", BindingFlags.NonPublic | BindingFlags.Instance).GetValue(this) as List<GridViewRowInfo>; List<GridViewColumn> orderedColumns = typeof(GridRowBehavior).GetField("orderedColumns", BindingFlags.NonPublic | BindingFlags.Instance).GetValue(this) as List<GridViewColumn>; if (verticalDirectionChange || horizontalDirectionChange) { int rowStartIndex = Math.Min(anchorRowIndex, currentRowIndex); int rowEndIndex = Math.Max(anchorRowIndex, currentRowIndex); int colStartIndex = Math.Min(anchorColumnIndex, currentColumnIndex); int colEndIndex = Math.Max(anchorColumnIndex, currentColumnIndex); for (int i = rowStartIndex; i <= rowEndIndex; i++) { for (int j = colStartIndex; j <= colEndIndex; j++) { GridViewCellInfo cell = orderedRows[i].Cells[orderedColumns[j].Index]; if (cell != null && cell.IsSelected) { cell.IsSelected = false; } } } } bool expandingSelectionUp = rowUnderMouseIndex < currentRowIndex && rowUnderMouseIndex < anchorRowIndex; bool expandingSelectionDown = rowUnderMouseIndex > currentRowIndex && rowUnderMouseIndex > anchorRowIndex; bool expandingSelectionLeft = columnUnderMouseIndex < currentColumnIndex && columnUnderMouseIndex < anchorColumnIndex; bool expandingSelectionRight = columnUnderMouseIndex > currentColumnIndex && columnUnderMouseIndex > anchorColumnIndex; if (expandingSelectionDown || expandingSelectionUp || expandingSelectionLeft || expandingSelectionRight) { int rowStartIndex = Math.Min(anchorRowIndex, rowUnderMouseIndex); int rowEndIndex = Math.Max(anchorRowIndex, rowUnderMouseIndex); int colStartIndex = Math.Min(anchorColumnIndex, columnUnderMouseIndex); int colEndIndex = Math.Max(anchorColumnIndex, columnUnderMouseIndex); for (int i = rowStartIndex; i <= rowEndIndex; i++) { for (int j = colStartIndex; j <= colEndIndex; j++) { if (i >= 0 && i < orderedRows.Count) { GridViewCellInfo cell = orderedRows[i].Cells[orderedColumns[j].Index]; if (cell != null && !cell.IsSelected) { cell.IsSelected = true; } } } } } else { bool shrinkingSelectionUp = rowUnderMouseIndex < currentRowIndex && rowUnderMouseIndex >= anchorRowIndex; bool shrinkingSelectionDown = rowUnderMouseIndex > currentRowIndex && rowUnderMouseIndex <= anchorRowIndex; bool shrinkingSelectionLeft = columnUnderMouseIndex < currentColumnIndex && columnUnderMouseIndex >= anchorColumnIndex; bool shrinkingSelectionRight = columnUnderMouseIndex > currentColumnIndex && columnUnderMouseIndex <= anchorColumnIndex; if (shrinkingSelectionUp || shrinkingSelectionDown) { int rowStartIndex = Math.Min(currentRowIndex, rowUnderMouseIndex); int rowEndIndex = Math.Max(currentRowIndex, rowUnderMouseIndex); int colStartIndex = Math.Min(anchorColumnIndex, columnUnderMouseIndex); int colEndIndex = Math.Max(anchorColumnIndex, columnUnderMouseIndex); if (shrinkingSelectionUp) { rowStartIndex += 1; } if (shrinkingSelectionDown) { rowEndIndex -= 1; } for (int i = rowStartIndex; i <= rowEndIndex; i++) { if (i != anchorRowIndex) { for (int j = colStartIndex; j <= colEndIndex; j++) { GridViewCellInfo cell = orderedRows[i].Cells[orderedColumns[j].Index]; if (cell != null && cell.IsSelected) { cell.IsSelected = false; } } } } } if (shrinkingSelectionLeft || shrinkingSelectionRight) { int rowStartIndex = Math.Min(anchorRowIndex, rowUnderMouseIndex); int rowEndIndex = Math.Max(anchorRowIndex, rowUnderMouseIndex); int colStartIndex = Math.Min(currentColumnIndex, columnUnderMouseIndex); int colEndIndex = Math.Max(currentColumnIndex, columnUnderMouseIndex); if (shrinkingSelectionLeft) { colStartIndex += 1; } if (shrinkingSelectionRight) { colEndIndex -= 1; } for (int i = rowStartIndex; i <= rowEndIndex; i++) { for (int j = colStartIndex; j <= colEndIndex; j++) { if (j != anchorColumnIndex && i >= 0 && i < orderedRows.Count) { GridViewCellInfo cell = orderedRows[i].Cells[orderedColumns[j].Index]; if (cell != null && cell.IsSelected) { cell.IsSelected = false; } } } } } } typeof(GridRowBehavior).GetField("currentRowIndex", BindingFlags.NonPublic | BindingFlags.Instance).SetValue(this, rowUnderMouseIndex); typeof(GridRowBehavior).GetField("currentColumnIndex", BindingFlags.NonPublic | BindingFlags.Instance).SetValue(this, columnUnderMouseIndex); return true; } private Rectangle GetViewportBounds(GridTableElement tableElement) { ScrollableRowsContainerElement scrollableRows = tableElement.ViewElement.ScrollableRows; Rectangle bounds = tableElement.ViewElement.ScrollableRows.ControlBoundingRectangle; for (int index = 0; index < scrollableRows.Children.Count; index++) { GridVirtualizedRowElement virtualizedRow = scrollableRows.Children[index] as GridVirtualizedRowElement; if (virtualizedRow != null) { VirtualizedColumnContainer scrollableColumns = virtualizedRow.ScrollableColumns; bounds.X = this.GridViewElement.RightToLeft ? virtualizedRow.RightPinnedColumns.ControlBoundingRectangle.Right : virtualizedRow.LeftPinnedColumns.ControlBoundingRectangle.Right; bounds.Width = scrollableColumns.ControlBoundingRectangle.Width; break; } } return bounds; } public override bool OnMouseMove(MouseEventArgs e) { Point currentLocation = e.Location; GridRowElement currentRow = this.RootGridBehavior.RowAtPoint; if (currentRow == null) { this.GridViewElement.TableElement.GetType().GetProperty("HoveredRow", BindingFlags.Instance | BindingFlags.NonPublic).SetValue(this.GridViewElement.TableElement, null); } if (e.Button == MouseButtons.None) { return this.ShowSizeNSCursort(currentLocation); } if (e.Button != MouseButtons.Left) { this.ResetControlCursor(); return false; } GridRowElement rowToResize = typeof(GridRowBehavior).GetField("rowToResize", BindingFlags.Instance | BindingFlags.NonPublic).GetValue(this) as GridRowElement; if (rowToResize != null) { this.ResizeRow(currentLocation); return true; } GridCellElement currentCell = this.RootGridBehavior.CellAtPoint; Point mouseDownLocation = (Point)typeof(GridRowBehavior).GetField("mouseDownLocation", BindingFlags.Instance | BindingFlags.NonPublic).GetValue(this); GridRowElement row = this.GetRowAtPoint(mouseDownLocation); bool result = false; if (currentCell != null && currentCell.ViewTemplate != null && !currentCell.ViewTemplate.AllowRowReorder && row != null) { result = this.ProcessMouseSelection(currentLocation, currentCell); } if ((currentCell == null || currentCell.ColumnInfo == null || currentCell.ColumnInfo.IsPinned || currentCell.RowInfo.IsPinned) && this.MasterTemplate.MultiSelect && mouseDownLocation != currentLocation) { typeof(GridRowBehavior).GetField("mouseMoveLocation", BindingFlags.Instance | BindingFlags.NonPublic).SetValue(this, currentLocation); System.Windows.Forms.Timer scrollTimer = typeof(GridRowBehavior).GetField("scrollTimer", BindingFlags.Instance | BindingFlags.NonPublic).GetValue(this) as System.Windows.Forms.Timer; if (!scrollTimer.Enabled) { scrollTimer.Enabled = true; } result = false; } return result; } } public class MyGridDataRowBehavior : GridDataRowBehavior { protected override bool ProcessMouseSelection(Point mousePosition, GridCellElement currentCell) { if (this.RootGridBehavior.LockedBehavior != this) { this.GridControl.Capture = true; this.RootGridBehavior.LockBehavior(this); } bool result = this.DoMouseSelection(currentCell, mousePosition); return result; } private bool DoMouseSelection(GridCellElement currentCell, Point currentLocation) { if (!this.MasterTemplate.MultiSelect || this.GridViewElement.Template.AllowRowReorder) { return false; } Point mouseDownLocation = (Point)typeof(GridRowBehavior).GetField("mouseDownLocation", BindingFlags.Instance | BindingFlags.NonPublic).GetValue(this); Rectangle rect = new Rectangle(mouseDownLocation.X - SystemInformation.DragSize.Width / 2, mouseDownLocation.Y - SystemInformation.DragSize.Height / 2, SystemInformation.DragSize.Width, SystemInformation.DragSize.Height); if (rect.Contains(currentLocation)) { return false; } GridTableElement tableElement = this.GridViewElement.CurrentView as GridTableElement; if (tableElement == null) { return false; } bool selectionStartedOnAPinnedColumn = (bool)typeof(GridRowBehavior).GetField("selectionStartedOnAPinnedColumn", BindingFlags.Instance | BindingFlags.NonPublic).GetValue(this); bool mouseDownOnLeftPinnedColumn = (bool)typeof(GridRowBehavior).GetField("mouseDownOnLeftPinnedColumn", BindingFlags.Instance | BindingFlags.NonPublic).GetValue(this); bool mouseDownOnRightPinnedColumn = (bool)typeof(GridRowBehavior).GetField("mouseDownOnRightPinnedColumn", BindingFlags.Instance | BindingFlags.NonPublic).GetValue(this); bool selectionStartedOnAPinnedRow = (bool)typeof(GridRowBehavior).GetField("selectionStartedOnAPinnedRow", BindingFlags.Instance | BindingFlags.NonPublic).GetValue(this); bool mouseDownOnTopPinnedRow = (bool)typeof(GridRowBehavior).GetField("mouseDownOnTopPinnedRow", BindingFlags.Instance | BindingFlags.NonPublic).GetValue(this); bool mouseDownOnBottomPinnedRow = (bool)typeof(GridRowBehavior).GetField("mouseDownOnBottomPinnedRow", BindingFlags.Instance | BindingFlags.NonPublic).GetValue(this); if (selectionStartedOnAPinnedColumn && this.GetViewportBounds(tableElement).Contains(currentLocation)) { if (mouseDownOnLeftPinnedColumn) { tableElement.HScrollBar.Value = tableElement.HScrollBar.Minimum; mouseDownOnLeftPinnedColumn = false; } if (mouseDownOnRightPinnedColumn) { tableElement.HScrollBar.Value = tableElement.HScrollBar.Maximum - tableElement.HScrollBar.LargeChange + 1; mouseDownOnRightPinnedColumn = false; } selectionStartedOnAPinnedColumn = false; } if (selectionStartedOnAPinnedRow && this.GetViewportBounds(tableElement).Contains(currentLocation)) { if (mouseDownOnTopPinnedRow) { tableElement.VScrollBar.Value = tableElement.VScrollBar.Minimum; mouseDownOnTopPinnedRow = false; } if (mouseDownOnBottomPinnedRow) { tableElement.VScrollBar.Value = tableElement.VScrollBar.Maximum - tableElement.VScrollBar.LargeChange + 1; mouseDownOnBottomPinnedRow = false; } selectionStartedOnAPinnedRow = false; } if (currentCell.RowInfo is GridViewDataRowInfo) { if (this.MasterTemplate.SelectionMode == GridViewSelectionMode.FullRowSelect) { typeof(GridHierarchyRowBehavior).GetMethod("DoMultiFullRowSelect", BindingFlags.Instance | BindingFlags.NonPublic).Invoke(this, new object[] { currentCell, currentLocation }); } else { this.DoMultiCellSelect(currentCell, currentLocation); } } return true; } private GridRowElement GetFirstScrollableRowElement(GridTableElement tableElement) { if (tableElement.ViewElement.ScrollableRows.Children.Count < 1) { return null; } return (GridRowElement)tableElement.ViewElement.ScrollableRows.Children[0]; } private GridViewColumn GetFirstScrollableColumn(GridTableElement tableElement) { GridRowElement rowElement = this.GetFirstScrollableRowElement(tableElement); if (rowElement == null) { return null; } int counter = 0; while (counter < rowElement.VisualCells.Count) { if (!rowElement.VisualCells[counter].IsPinned && rowElement.VisualCells[counter].ColumnInfo is GridViewDataColumn) { return rowElement.VisualCells[counter].ColumnInfo; } counter++; } return null; } private int GetRowIndex(GridViewRowInfo rowInfo) { List<GridViewRowInfo> orderedRows = typeof(GridRowBehavior).GetField("orderedRows", BindingFlags.NonPublic | BindingFlags.Instance).GetValue(this) as List<GridViewRowInfo>; return orderedRows.IndexOf(rowInfo); } private void DoMultiCellSelect(GridCellElement currentCell, Point currentLocation) { #region GridViewSelection int rowUnderMouseIndex = this.GetRowIndex(this.RootGridBehavior.RowAtPoint.RowInfo); int columnUnderMouseIndex = 0; GridTableElement tableElement = this.GridViewElement.CurrentView as GridTableElement; GridViewColumn col = this.RootGridBehavior.CellAtPoint.ColumnInfo; if (this.RootGridBehavior.CellAtPoint.ColumnInfo is GridViewRowHeaderColumn) { col = this.GetFirstScrollableColumn(tableElement); } List<GridViewRowInfo> orderedRows = typeof(GridRowBehavior).GetField("orderedRows", BindingFlags.NonPublic | BindingFlags.Instance).GetValue(this) as List<GridViewRowInfo>; List<GridViewColumn> orderedColumns = typeof(GridRowBehavior).GetField("orderedColumns", BindingFlags.NonPublic | BindingFlags.Instance).GetValue(this) as List<GridViewColumn>; if (col != null) { columnUnderMouseIndex = orderedColumns.IndexOf(col); } List<GridViewRowInfo> rows = new List<GridViewRowInfo>(); int anchorRowIndex = (int)typeof(GridRowBehavior).GetField("anchorRowIndex", BindingFlags.NonPublic | BindingFlags.Instance).GetValue(this); int startIndex = Math.Min(anchorRowIndex, rowUnderMouseIndex); int endIndex = Math.Max(anchorRowIndex, rowUnderMouseIndex); for (int i = startIndex; i < endIndex; i++) { if (i < 0) { continue; } if (orderedRows.Count > i) { rows.Add(orderedRows[i]); } } int anchorColumnIndex = (int)typeof(GridRowBehavior).GetField("anchorColumnIndex", BindingFlags.NonPublic | BindingFlags.Instance).GetValue(this); int columnLeft = Math.Min(anchorColumnIndex, columnUnderMouseIndex); int columnRight = Math.Max(anchorColumnIndex, columnUnderMouseIndex); GridViewSelectionCancelEventArgs cancelArgs = new GridViewSelectionCancelEventArgs(rows, columnLeft, columnRight); this.MasterTemplate.EventDispatcher.RaiseEvent<GridViewSelectionCancelEventArgs>(EventDispatcher.SelectionChanging, this, cancelArgs); if (cancelArgs.Cancel) { return; } #endregion bool isProcessedShiftOrControl = this.IsPressedShift || this.IsPressedControl; ObservableCollection<GridViewCellInfo> SelectedCells = typeof(GridViewSelectedCellsCollection).GetProperty("ObservableItems", BindingFlags.Instance | BindingFlags.NonPublic).GetValue(this.MasterTemplate.SelectedCells) as ObservableCollection<GridViewCellInfo>; SelectedCells.BeginUpdate(); this.GridViewElement.CurrentView.BeginUpdate(); int count = this.MasterTemplate.SelectedCells.Count; bool notifyUpdates = this.ProcessCellSelection(rowUnderMouseIndex, columnUnderMouseIndex); if (isProcessedShiftOrControl) { notifyUpdates = count != this.MasterTemplate.SelectedCells.Count; } this.GridViewElement.CurrentView.EndUpdate(false); SelectedCells.EndUpdate(notifyUpdates); } private bool ProcessCellSelection(int rowUnderMouseIndex, int columnUnderMouseIndex) { int currentRowIndex = (int)typeof(GridRowBehavior).GetField("currentRowIndex", BindingFlags.NonPublic | BindingFlags.Instance).GetValue(this); int anchorRowIndex = (int)typeof(GridRowBehavior).GetField("anchorRowIndex", BindingFlags.NonPublic | BindingFlags.Instance).GetValue(this); int currentColumnIndex = (int)typeof(GridRowBehavior).GetField("currentColumnIndex", BindingFlags.NonPublic | BindingFlags.Instance).GetValue(this); int anchorColumnIndex = (int)typeof(GridRowBehavior).GetField("anchorColumnIndex", BindingFlags.NonPublic | BindingFlags.Instance).GetValue(this); if ((rowUnderMouseIndex == currentRowIndex && columnUnderMouseIndex == currentColumnIndex) || (rowUnderMouseIndex < 0 || columnUnderMouseIndex < 0)) { return false; } bool verticalDirectionChange = (rowUnderMouseIndex < currentRowIndex && currentRowIndex > anchorRowIndex && rowUnderMouseIndex < anchorRowIndex) || (rowUnderMouseIndex > currentRowIndex && currentRowIndex < anchorRowIndex && rowUnderMouseIndex > anchorRowIndex); bool horizontalDirectionChange = (columnUnderMouseIndex < currentColumnIndex && currentColumnIndex > anchorColumnIndex && columnUnderMouseIndex < anchorColumnIndex) || (columnUnderMouseIndex > currentColumnIndex && currentColumnIndex < anchorColumnIndex && columnUnderMouseIndex > anchorColumnIndex); List<GridViewRowInfo> orderedRows = typeof(GridRowBehavior).GetField("orderedRows", BindingFlags.NonPublic | BindingFlags.Instance).GetValue(this) as List<GridViewRowInfo>; List<GridViewColumn> orderedColumns = typeof(GridRowBehavior).GetField("orderedColumns", BindingFlags.NonPublic | BindingFlags.Instance).GetValue(this) as List<GridViewColumn>; if (verticalDirectionChange || horizontalDirectionChange) { int rowStartIndex = Math.Min(anchorRowIndex, currentRowIndex); int rowEndIndex = Math.Max(anchorRowIndex, currentRowIndex); int colStartIndex = Math.Min(anchorColumnIndex, currentColumnIndex); int colEndIndex = Math.Max(anchorColumnIndex, currentColumnIndex); for (int i = rowStartIndex; i <= rowEndIndex; i++) { for (int j = colStartIndex; j <= colEndIndex; j++) { GridViewCellInfo cell = orderedRows[i].Cells[orderedColumns[j].Index]; if (cell != null && cell.IsSelected) { cell.IsSelected = false; } } } } bool expandingSelectionUp = rowUnderMouseIndex < currentRowIndex && rowUnderMouseIndex < anchorRowIndex; bool expandingSelectionDown = rowUnderMouseIndex > currentRowIndex && rowUnderMouseIndex > anchorRowIndex; bool expandingSelectionLeft = columnUnderMouseIndex < currentColumnIndex && columnUnderMouseIndex < anchorColumnIndex; bool expandingSelectionRight = columnUnderMouseIndex > currentColumnIndex && columnUnderMouseIndex > anchorColumnIndex; if (expandingSelectionDown || expandingSelectionUp || expandingSelectionLeft || expandingSelectionRight) { int rowStartIndex = Math.Min(anchorRowIndex, rowUnderMouseIndex); int rowEndIndex = Math.Max(anchorRowIndex, rowUnderMouseIndex); int colStartIndex = Math.Min(anchorColumnIndex, columnUnderMouseIndex); int colEndIndex = Math.Max(anchorColumnIndex, columnUnderMouseIndex); for (int i = rowStartIndex; i <= rowEndIndex; i++) { for (int j = colStartIndex; j <= colEndIndex; j++) { GridViewCellInfo cell = orderedRows[i].Cells[orderedColumns[j].Index]; if (cell != null && !cell.IsSelected) { cell.IsSelected = true; } } } } else { bool shrinkingSelectionUp = rowUnderMouseIndex < currentRowIndex && rowUnderMouseIndex >= anchorRowIndex; bool shrinkingSelectionDown = rowUnderMouseIndex > currentRowIndex && rowUnderMouseIndex <= anchorRowIndex; bool shrinkingSelectionLeft = columnUnderMouseIndex < currentColumnIndex && columnUnderMouseIndex >= anchorColumnIndex; bool shrinkingSelectionRight = columnUnderMouseIndex > currentColumnIndex && columnUnderMouseIndex <= anchorColumnIndex; if (shrinkingSelectionUp || shrinkingSelectionDown) { int rowStartIndex = Math.Min(currentRowIndex, rowUnderMouseIndex); int rowEndIndex = Math.Max(currentRowIndex, rowUnderMouseIndex); int colStartIndex = Math.Min(anchorColumnIndex, columnUnderMouseIndex); int colEndIndex = Math.Max(anchorColumnIndex, columnUnderMouseIndex); if (shrinkingSelectionUp) { rowStartIndex += 1; } if (shrinkingSelectionDown) { rowEndIndex -= 1; } for (int i = rowStartIndex; i <= rowEndIndex; i++) { if (i != anchorRowIndex) { for (int j = colStartIndex; j <= colEndIndex; j++) { GridViewCellInfo cell = orderedRows[i].Cells[orderedColumns[j].Index]; if (cell != null && cell.IsSelected) { cell.IsSelected = false; } } } } } if (shrinkingSelectionLeft || shrinkingSelectionRight) { int rowStartIndex = Math.Min(anchorRowIndex, rowUnderMouseIndex); int rowEndIndex = Math.Max(anchorRowIndex, rowUnderMouseIndex); int colStartIndex = Math.Min(currentColumnIndex, columnUnderMouseIndex); int colEndIndex = Math.Max(currentColumnIndex, columnUnderMouseIndex); if (shrinkingSelectionLeft) { colStartIndex += 1; } if (shrinkingSelectionRight) { colEndIndex -= 1; } for (int i = rowStartIndex; i <= rowEndIndex; i++) { for (int j = colStartIndex; j <= colEndIndex; j++) { if (j != anchorColumnIndex) { GridViewCellInfo cell = orderedRows[i].Cells[orderedColumns[j].Index]; if (cell != null && cell.IsSelected) { cell.IsSelected = false; } } } } } } typeof(GridRowBehavior).GetField("currentRowIndex", BindingFlags.NonPublic | BindingFlags.Instance).SetValue(this, rowUnderMouseIndex); typeof(GridRowBehavior).GetField("currentColumnIndex", BindingFlags.NonPublic | BindingFlags.Instance).SetValue(this, columnUnderMouseIndex); return true; } private Rectangle GetViewportBounds(GridTableElement tableElement) { ScrollableRowsContainerElement scrollableRows = tableElement.ViewElement.ScrollableRows; Rectangle bounds = tableElement.ViewElement.ScrollableRows.ControlBoundingRectangle; for (int index = 0; index < scrollableRows.Children.Count; index++) { GridVirtualizedRowElement virtualizedRow = scrollableRows.Children[index] as GridVirtualizedRowElement; if (virtualizedRow != null) { VirtualizedColumnContainer scrollableColumns = virtualizedRow.ScrollableColumns; bounds.X = this.GridViewElement.RightToLeft ? virtualizedRow.RightPinnedColumns.ControlBoundingRectangle.Right : virtualizedRow.LeftPinnedColumns.ControlBoundingRectangle.Right; bounds.Width = scrollableColumns.ControlBoundingRectangle.Width; break; } } return bounds; } public override bool OnMouseMove(MouseEventArgs e) { Point currentLocation = e.Location; GridRowElement currentRow = this.RootGridBehavior.RowAtPoint; if (currentRow == null) { this.GridViewElement.TableElement.GetType().GetProperty("HoveredRow", BindingFlags.Instance | BindingFlags.NonPublic).SetValue(this.GridViewElement.TableElement, null); } if (e.Button == MouseButtons.None) { return this.ShowSizeNSCursort(currentLocation); } if (e.Button != MouseButtons.Left) { this.ResetControlCursor(); return false; } GridRowElement rowToResize = typeof(GridRowBehavior).GetField("rowToResize", BindingFlags.Instance | BindingFlags.NonPublic).GetValue(this) as GridRowElement; if (rowToResize != null) { this.ResizeRow(currentLocation); return true; } GridCellElement currentCell = this.RootGridBehavior.CellAtPoint; Point mouseDownLocation = (Point)typeof(GridRowBehavior).GetField("mouseDownLocation", BindingFlags.Instance | BindingFlags.NonPublic).GetValue(this); GridRowElement row = this.GetRowAtPoint(mouseDownLocation); bool result = false; if (currentCell != null && currentCell.ViewTemplate != null && !currentCell.ViewTemplate.AllowRowReorder && row != null) { result = this.ProcessMouseSelection(currentLocation, currentCell); } if ((currentCell == null || currentCell.ColumnInfo == null || currentCell.ColumnInfo.IsPinned || currentCell.RowInfo.IsPinned) && this.MasterTemplate.MultiSelect && mouseDownLocation != currentLocation) { typeof(GridRowBehavior).GetField("mouseMoveLocation", BindingFlags.Instance | BindingFlags.NonPublic).SetValue(this, currentLocation); System.Windows.Forms.Timer scrollTimer = typeof(GridRowBehavior).GetField("scrollTimer", BindingFlags.Instance | BindingFlags.NonPublic).GetValue(this) as System.Windows.Forms.Timer; if (!scrollTimer.Enabled) { scrollTimer.Enabled = true; } result = false; } return result; } }