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;
}
}