Make the DataGrid support single select vs multiselect mode.
You can do this by subclassing your DataGrid and
overriding the OnMouseMove and OnMouseDown
methods. I also add a new SingleSelect property to
the DataGrid so you can toggle single selection on and off.
Add these module level variables:
' Single row selection flag.
Private mySingleSelect As Boolean = False
' Used to see what part of grid was clicked.
Private myHitTestInfo As DataGrid.HitTestInfo
Private myOldSelectedRow As Integer
Add this property:
Public Property SingleSelect() As Boolean
Get
SingleSelect = mySingleSelect
End Get
Set(ByVal theValue As Boolean)
mySingleSelect = theValue
End Set
End Property
Add these methods:
Protected Overloads Overrides Sub OnMouseMove(ByVal e As MouseEventArgs)
'
' Make the DataGrid support single select mode vs the
' default multiselect mode. Don't call the base class if
' left mouse down to avoid dragging selections.
'
On Error Resume Next
If (e.Button <> MouseButtons.Left) Or Not mySingleSelect Then
MyBase.OnMouseMove(e)
End If
End Sub
Protected Overloads Overrides Sub OnMouseDown(ByVal e As MouseEventArgs)
'
' Make the DataGrid support single select mode vs the default multiselect mode.
' Handle selecting and unselecting without calling the base class if the click
' is on the header
'
On Error Resume Next
myHitTestInfo = Me.HitTest(New Point(e.X, e.Y))
If (myHitTestInfo.Type = Me.HitTestType.Cell) Then
'
' When a grid cell is clicked prevent multi-select.
'
If mySingleSelect Then
If myOldSelectedRow > -1 Then
'
' Account for deleted rows.
'
Dim cm As CurrencyManager = _
CType(Me.BindingContext(Me.DataSource), CurrencyManager)
If myOldSelectedRow > cm.Count - 1 Then
myOldSelectedRow = cm.Count - 1
End If
Me.UnSelect(myOldSelectedRow)
End If
myOldSelectedRow = -1
End If
MyBase.OnMouseDown(e)
Else
'
' Prevent row resizing and multi-select.
'
If (myHitTestInfo.Type = Me.HitTestType.RowHeader) Then
If myOldSelectedRow > -1 And mySingleSelect Then
'
' Account for deleted rows.
'
Dim cm As CurrencyManager = _
CType(Me.BindingContext(Me.DataSource), CurrencyManager)
If myOldSelectedRow > cm.Count - 1 Then
myOldSelectedRow = cm.Count - 1
End If
Me.UnSelect(myOldSelectedRow)
End If
If ((Control.ModifierKeys And Keys.Shift) = 0) Then
MyBase.OnMouseDown(e)
Else
If mySingleSelect Then
Me.CurrentCell = _
New DataGridCell(myHitTestInfo.Row, myHitTestInfo.Column)
End If
End If
Me.Select(myHitTestInfo.Row)
myOldSelectedRow = myHitTestInfo.Row
End If
End If
End Sub
For the C# programmer, add these fields:
// Single row selection flag.
private bool mySingleSelect = false;
// Used to see what part of grid was clicked.
private DataGrid.HitTestInfo myHitTestInfo;
private int myOldSelectedRow;
Add this property:
public bool SingleSelect
{
get
{
return mySingleSelect;
}
set
{
mySingleSelect = value;
}
}
Add these methods:
protected override void OnMouseMove(MouseEventArgs e)
{
//
// Make the DataGrid support single select mode vs the default multiselect mode.
// Don't call the base class if left mouse down to avoid dragging selections.
//
if ((e.Button != MouseButtons.Left) | (mySingleSelect == false))
{
base.OnMouseMove(e);
}
}
protected override void OnMouseDown(MouseEventArgs e)
{
//
// Make the DataGrid support single select mode vs the default multiselect mode.
// Handle selecting and unselecting without calling the base class if the click
// is on the header
//
myHitTestInfo = this.HitTest(new Point(e.X, e.Y));
if (myHitTestInfo.Type == HitTestType.Cell)
{
//
// When a grid cell is clicked prevent multi-select.
//
if (mySingleSelect)
{
if (myOldSelectedRow > -1)
{
//
// Account for deleted rows.
//
CurrencyManager cm = (CurrencyManager)this.BindingContext[this.DataSource];
if (myOldSelectedRow > cm.Count - 1
myOldSelectedRow = cm.Count - 1;
this.UnSelect(myOldSelectedRow);
}
myOldSelectedRow = -1;
}
base.OnMouseDown(e);
}
else
{
//
// Prevent row resizing and multi-select.
//
if (myHitTestInfo.Type == HitTestType.RowHeader)
{
if ((myOldSelectedRow > -1) & (mySingleSelect))
{
//
// Account for deleted rows.
//
CurrencyManager cm = (CurrencyManager)this.BindingContext[this.DataSource];
if (myOldSelectedRow > cm.Count - 1)
myOldSelectedRow = cm.Count - 1;
this.UnSelect(myOldSelectedRow);
}
if ((Control.ModifierKeys & Keys.Shift) == 0)
base.OnMouseDown(e);
else
{
if (mySingleSelect)
this.CurrentCell = new DataGridCell(myHitTestInfo.Row, myHitTestInfo.Column);
}
this.Select(myHitTestInfo.Row);
myOldSelectedRow = myHitTestInfo.Row;
}
} //else
} // OnMouseDown
|