vb.net DevExperess winforms gridview mouse down event - vb.net

I have a problem with MouseDown event for GridControl with GridView.
If user press control + shift + click column header is to select the column and also click the most top left will select all row. I managed to do that but either one will work for my code. It seems the logic have some problem with if-else statement. Anyone can help?
Private Sub gridView1_MouseDown(ByVal sender As Object, ByVal e As MouseEventArgs) Handles GridView1.MouseDown
If Control.ModifierKeys = (Keys.Control) Then
Dim view As GridView = CType(sender, GridView)
Dim hInfo As GridHitInfo = view.CalcHitInfo(e.Location)
If hInfo.InColumn Then
view.ClearSelection()
SelectCells(hInfo.Column)
Else
Return
End If
CType(e, DXMouseEventArgs).Handled = True
ElseIf Control.ModifierKeys = Nothing Then
Dim view As GridView = CType(sender, GridView)
view.ClearSelection()
Return
Else
Dim view2 As GridView = CType(sender, GridView)
Dim hitInfo As GridHitInfo = view2.CalcHitInfo(e.Location)
If hitInfo.HitTest = GridHitTest.ColumnButton Then
view2.SelectAll()
End If
CType(e, DXMouseEventArgs).Handled = True
End If
End Sub
Private Sub SelectCells(ByVal column As GridColumn)
Dim view As GridView = CType(column.View, GridView)
view.BeginSelection()
For i As Integer = 0 To column.View.RowCount - 1
view.SelectCell(i, column)
Next i
view.EndSelection()
End Sub

You can use Select Case statement to rearrange your statements.
Here is example:
Private Sub gridView1_MouseDown(ByVal sender As Object, ByVal e As MouseEventArgs) Handles gridView1.MouseDown
Dim view As GridView = CType(sender, GridView)
Dim hInfo As GridHitInfo = view.CalcHitInfo(e.Location)
Select Case True
Case hInfo.HitTest = GridHitTest.ColumnButton
view.SelectAll()
Case Control.ModifierKeys = Nothing
view.ClearSelection()
Return
Case hInfo.InColumn AndAlso Control.ModifierKeys = (Keys.Shift Or Keys.Control)
view.ClearSelection()
SelectCells(hInfo.Column)
Case Else
Return
End Select
CType(e, DXMouseEventArgs).Handled = True
End Sub

Related

ComboBox Control within DatagridView

I want to use DGV as a table to take User’s inputs. And in few columns, I want User to select values from a collection hence I decided to use Comboboxcontrol. I selected a standard DGV ("DGV2") and a standard Combobox ("CBTest") as tools. And I programmed this Combo to appear on Columnindex 2 (when user enters the particular cell, Combo box pops-up). User can select from the combo items (Drop-Down-List) and after selection clicked done, curser moves to next column.
Now there is problems with UP/DOWN Keys when control is in cell having COMBO-BOX-
I am not able to control behavior of UP /DOWN Keys when user enters the Cell having COMBO Control.
Sometime with up-down keys cursor moves between Combobox items and sometimes it jumps in other rows.
I am a beginner so any hint and help will be useful.
Code I used -
Public Class frmSIDDGV
Dim nCol As Integer = 0
Dim nRow As Integer = 0
Private Sub frmSIDDGV_Load(sender As Object, e As EventArgs) Handles MyBase.Load
With DGV2
.AllowUserToAddRows = False
.AllowUserToDeleteRows = False
.AutoSizeColumnsMode = DataGridViewAutoSizeColumnsMode.Fill
.AutoResizeColumns()
.RowTemplate.Height = 40
.RowHeadersVisible = False
End With
DGV2.ColumnCount = 5
With DGV2
.Columns(0).Name = "Item"
.Columns(1).Name = "MRP"
.Columns(2).Name = "Qty"
.Columns(3).Name = "Unit"
.Columns(4).Name = "Amount"
End With
DGV2.Rows.Add()
DGV2(0, 0).Value = 1
End Sub
Private Sub DGV2_KeyUp(sender As Object, e As KeyEventArgs) Handles DGV2.KeyUp
If e.KeyCode = Keys.Enter Then
If ActiveControl.Name <> "CBTest" Then
If nCol = DGV2.ColumnCount - 1 Then
DGV2.Rows.Add()
DGV2.CurrentCell = DGV2(0, nRow + 1)
Else
DGV2.CurrentCell = DGV2(nCol + 1, nRow)
End If
End If
ElseIf e.KeyCode = Keys.Escape Then
If ActiveControl.Name = "CBTest" Then
CBTest.SelectedIndex = 0 : CBTest.Visible = False
DGV2.CurrentCell = DGV2(nCol, nRow)
DGV2.Focus()
End If
End If
End Sub
Private Sub DGV2_CurrentCellChanged(sender As Object, e As EventArgs) Handles DGV2.CurrentCellChanged
Try
nCol = DGV2.CurrentCell.ColumnIndex
nRow = DGV2.CurrentCell.RowIndex
Catch ex As Exception
nCol = 0
nRow = 0
End Try
End Sub
Private Sub DGV2_CellEnter(sender As Object, e As DataGridViewCellEventArgs) Handles DGV2.CellEnter
Select Case e.ColumnIndex
Case 2 ' User entered in Cell name "Item"
DGV2.Controls.Add(CBTest)
'DGV2.BeginEdit(True)
Dim oRectangle = DGV2.GetCellDisplayRectangle(e.ColumnIndex, e.RowIndex, True)
CBTest.Size = New Size(oRectangle.Width, oRectangle.Height)
CBTest.Location = New Point(oRectangle.X, oRectangle.Y)
CBTest.Visible = True
SendKeys.Send("{F4}")
CBTest.SelectedIndex = 0
CBTest.Capture = True
CBTest.Focus()
End Select
End Sub
Private Sub CBTest_SelectionChangeCommitted(sender As Object, e As EventArgs) Handles CBTest.SelectionChangeCommitted
With DGV2
.Focus()
.Item(nCol, nRow).Value = Trim(CBTest.Text)
.CurrentCell = .Rows(.CurrentRow.Index).Cells(nCol + 1)
End With
CBTest.Visible = False
End Sub
End Class

ListView: MultiSelect items with mouse drag

In ListView, I can press Ctrl + Shift and click on the item to select. But, I want to drag the mouse to select the items (like DataGridView). I tried this code (below) and I had a problem like this:
My code:
Private mouseDownLV As Boolean
Private Sub ListView1_MouseDown(sender As Object, e As System.Windows.Forms.MouseEventArgs) Handles ListView1.MouseDown
mouseDownLV = True
End Sub
Private Sub ListView1_MouseMove(sender As Object, e As System.Windows.Forms.MouseEventArgs) Handles ListView1.MouseMove
If mouseDownLV Then
Try
Dim i = ListView1.HitTest(e.Location).Item.Index
ListView1.Items(i).Selected = True
Catch ' ex As Exception
End Try
End If
End Sub
Private Sub ListView1_MouseUp(sender As Object, e As System.Windows.Forms.MouseEventArgs) Handles ListView1.MouseUp
mouseDownLV = False
End Sub
Actually you need to iterate through the currently displayed ListViewItem objects and toggle the Selected property of the items that intersect with the mouse movement. Here's a way to achieve that:
Declare a class member named startPoint:
Private startPoint As Point
Handle the MouseDown event to set the starting position:
Private Sub ListView1_MouseDown(sender As Object, e As MouseEventArgs) Handles ListView1.MouseDown
Dim s = DirectCast(sender, ListView)
If e.Button = MouseButtons.Left AndAlso
s.Items.Count > 1 Then
startPoint = e.Location
End If
End Sub
Handle the MouseMove event to toggle the Selected property:
Private Sub ListView1_MouseMove(sender As Object, e As MouseEventArgs) Handles ListView1.MouseMove
Dim s = DirectCast(sender, ListView)
If e.Button = MouseButtons.Left AndAlso s.Items.Count > 1 Then
Dim selRect As New Rectangle(Math.Min(startPoint.X, e.Location.X),
Math.Min(startPoint.Y, e.Location.Y),
Math.Abs(e.Location.X - startPoint.X),
Math.Abs(e.Location.Y - startPoint.Y))
Dim cr = s.ClientRectangle
'Toggle selection...
For Each item In s.Items.Cast(Of ListViewItem).
Where(Function(x) x.Bounds.IntersectsWith(cr))
item.Selected = selRect.IntersectsWith(item.Bounds)
Next
End If
End Sub
A quick demo to check that:
But what if you have many items where the size of the client area is not large enough to display them all and thus the vertical scrollbar is visible? You will get something like this:
As you can see, the vertical scrollbar does not move and you won't be able to continue selecting/deselecting the hidden items. To fix that, we need some more code:
Import the signature of the GetScrollPos function somewhere in your class:
Imports System.Runtime.InteropServices
'...
<DllImport("user32.dll", CharSet:=CharSet.Auto)>
Private Shared Function GetScrollPos(hWnd As IntPtr,
nBar As Orientation) As Integer
End Function
Note: Passing a System.Windows.Forms.Orientation value instead of an Interger.
Change the MouseDown event to:
Private Sub ListView1_MouseDown(sender As Object, e As MouseEventArgs) Handles ListView1.MouseDown
Dim s = DirectCast(sender, ListView)
If e.Button = MouseButtons.Left AndAlso
s.Items.Count > 1 Then
Dim vsp = GetScrollPos(s.Handle, Orientation.Vertical)
Dim yOffset = s.Font.Height * vsp
startPoint = New Point(e.X, e.Y + yOffset)
End If
End Sub
And the MouseMove event to:
Private Sub ListView1_MouseMove(sender As Object, e As MouseEventArgs) Handles ListView1.MouseMove
Dim s = DirectCast(sender, ListView)
If e.Button = MouseButtons.Left AndAlso s.Items.Count > 1 Then
Dim vsp = GetScrollPos(s.Handle, Orientation.Vertical)
Dim yOffset = s.Font.Height * vsp
Dim selRect As New Rectangle(Math.Min(startPoint.X, e.Location.X),
Math.Min(startPoint.Y - yOffset, e.Location.Y),
Math.Abs(e.Location.X - startPoint.X),
Math.Abs(e.Location.Y - startPoint.Y + yOffset))
Dim cr = s.ClientRectangle
'Toggle selection...
For Each item In s.Items.Cast(Of ListViewItem).
Where(Function(x) x.Bounds.IntersectsWith(cr))
item.Selected = selRect.IntersectsWith(item.Bounds)
Next
'Scroll if needed...
Dim p = s.PointToClient(Cursor.Position)
Dim lvi = s.GetItemAt(p.X, p.Y)
If lvi Is Nothing Then Return
Dim fh = s.Font.Height
If lvi.Index > 0 AndAlso (p.Y - lvi.Bounds.Height * 1.5) <= fh Then
s.Items(lvi.Index - 1).EnsureVisible()
ElseIf lvi.Index < s.Items.Count - 1 AndAlso
(p.Y + lvi.Bounds.Height * 1.5) > (s.Height - fh) Then
s.Items(lvi.Index + 1).EnsureVisible()
End If
End If
End Sub
The outcome is:
Here is VB.NET custom ListView control for this problem, and another in C#.

ListViewItem.Selected=True being overridden?

Hullo, there. First post. Please be gentle.
I am trying to move a selected item up and down a ListView control using the up and down arrows keys.
Here is my code. It is a Windows Forms project, with a form and a ListView control. MultiSelect=False. Sorting=None. View=Details. A single column.
Private Sub Form1_Load(sender As Object, e As EventArgs) Handles Me.Load
ListView1.Items.Add("A")
ListView1.Items.Add("B")
ListView1.Items.Add("C")
ListView1.Items.Add("D")
ListView1.Items.Add("E")
End Sub
Private Sub ListView1_KeyDown(sender As Object, e As KeyEventArgs) Handles ListView1.KeyDown
Dim iInsertAt As Integer
If ListView1.SelectedItems.Count = 1 Then
Dim lSelectedItem As ListViewItem = ListView1.SelectedItems(0)
Select Case e.KeyCode
Case Keys.Up
If lSelectedItem.Index > 0 Then
iInsertAt = lSelectedItem.Index - 1
ListView1.Items.Remove(lSelectedItem)
lSelectedItem = ListView1.Items.Insert(iInsertAt, lSelectedItem)
End If
Case Keys.Down
If lSelectedItem.Index < ListView1.Items.Count - 1 Then
iInsertAt = lSelectedItem.Index + 1
ListView1.Items.Remove(lSelectedItem)
lSelectedItem = ListView1.Items.Insert(iInsertAt, lSelectedItem)
End If
End Select
lSelectedItem.Selected = True
End If
End Sub
The code works fine, except that it does not correctly highlight lSelectedItem when it has been moved ^up^. If you run the code, you can select "A" and shift it down the list with the down arrow key. But the result with the up arrow key is not so good.
Would appreciate any guidance!
Thanks.
That's happened because when you remove the item, the selected index still the same so the selection goes to the next item.
For more information
To correct that you can do something like remove and insert two items from the list In order to maintain the order of the selected index.
ex:
Private Sub Form1_Load(sender As Object, e As EventArgs) Handles Me.Load
ListView1.Items.Add("A")
ListView1.Items.Add("B")
ListView1.Items.Add("C")
ListView1.Items.Add("D")
ListView1.Items.Add("E")
End Sub
Private Sub ListView1_KeyDown(sender As Object, e As KeyEventArgs) Handles ListView1.KeyDown
Dim iInsertAt As Integer
If ListView1.SelectedItems.Count = 1 Then
Dim lSelectedItem As ListViewItem = ListView1.SelectedItems(0)
Select Case e.KeyCode
Case Keys.Up
If lSelectedItem.Index > 0 Then
iInsertAt = lSelectedItem.Index - 1
Dim item2 = ListView1.Items.Item(iInsertAt)
'remove and Insert two
ListView1.Items.Remove(item2)
ListView1.Items.Insert(iInsertAt + 1, item2)
ListView1.Items.Remove(lSelectedItem)
lSelectedItem = ListView1.Items.Insert(iInsertAt, lSelectedItem)
End If
Case Keys.Down
If lSelectedItem.Index < ListView1.Items.Count - 1 Then
iInsertAt = lSelectedItem.Index + 1
ListView1.Items.Remove(lSelectedItem)
lSelectedItem = ListView1.Items.Insert(iInsertAt, lSelectedItem)
End If
End Select
End If
End Sub

How to select multiple rows OR columns keeping "Ctrl" pressed in DataGridView object

I adapted code from this question
how to select rows on cellclick, and also columns on column header click?
into a single DataGridView1_MouseDown event, because it wasn't allowing me to select multiple rows/columns using the "Ctrl" key.
What I'd like, is to be able to select multiple rows (clicking on the row indices) OR multiple columns (clicking on the column headers) by selecting one after another keeping "Ctrl" pressed. I can easily get one OR the other (setting DataGridViewSelectionMode to either FullRowSelect or ColumnHeaderSelect) and then Ctrl works, but I'd like to have both functionality on the same DataGridView.
I feel like I'm so close. Thanks for any tips!
Private Sub DataGridView1_MouseDown(ByVal sender As System.Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles DataGridView1.MouseDown
Dim ht As DataGridView.HitTestInfo
ht = Me.DataGridView1.HitTest(e.X, e.Y)
If e.Button = Windows.Forms.MouseButtons.Left Then
If ht.Type = DataGridViewHitTestType.Cell Then
DataGridView1.SelectionMode = DataGridViewSelectionMode.CellSelect
DataGridView1.CurrentCell.Selected = True
ElseIf ht.Type = DataGridViewHitTestType.RowHeader Then
DataGridView1.SelectionMode = DataGridViewSelectionMode.FullRowSelect
DataGridView1.Rows(ht.RowIndex).Selected = True
ElseIf ht.Type = DataGridViewHitTestType.ColumnHeader Then
DataGridView1.SelectionMode = DataGridViewSelectionMode.ColumnHeaderSelect
DataGridView1.Columns(ht.ColumnIndex).Selected = True
End If
End If
End Sub
I don't think you will be able to use both full column and full row select at the same time, after running some tests, it seems that changing the datagridview's selectionmode is what's clearing selections when it is set...so unless you were to create a custom control that inherits from datagridview and overrides some of its internals, you may be stuck. Without doing that, the only way I was able to achieve the behavior you're trying to get was to leave the datagridview cellselection mode set to cellselect, and do the row/column selections manually:
Private Sub DataGridView1_MouseDown(ByVal sender As System.Object, ByVal e As System.Windows.Forms.MouseEventArgs) _
Handles DataGridView1.MouseDown
If e.Button = Windows.Forms.MouseButtons.Left Then
Dim ht As DataGridView.HitTestInfo = Me.DataGridView1.HitTest(e.X, e.Y)
If Not My.Computer.Keyboard.CtrlKeyDown Then DataGridView1.ClearSelection()
If ht.Type = DataGridViewHitTestType.Cell Then
DataGridView1.CurrentCell.Selected = True
ElseIf ht.Type = DataGridViewHitTestType.RowHeader Then
For i As Integer = 0 To DataGridView1.Columns.Count - 1
DataGridView1.Rows(ht.RowIndex).Cells(i).Selected = True
Next
ElseIf ht.Type = DataGridViewHitTestType.ColumnHeader Then
For i As Integer = 0 To DataGridView1.Rows.Count - 1
DataGridView1.Rows(i).Cells(ht.ColumnIndex).Selected = True
Next
End If
End If
End Sub

vb.net DexExpress winform GridControl click column header select cell

I use GridControl with Gridview to display the data. I realized I click the column header is sorting the data instead of select all cell under the column header. May I know how to handle this? I have a sample code (below) but it use BandedGridview.
Private Sub bandedGridView1_MouseDown(ByVal sender As Object, ByVal e As MouseEventArgs) Handles bandedGridView1.MouseDown
If Control.ModifierKeys <> (Keys.Shift Or Keys.Control) Then
Return
End If
Dim view As BandedGridView = CType(sender, BandedGridView)
Dim hInfo As BandedGridHitInfo = view.CalcHitInfo(e.Location)
If hInfo.InColumn Then
view.ClearSelection()
SelectCells(hInfo.Column)
ElseIf hInfo.InBandPanel AndAlso hInfo.Band IsNot Nothing Then
view.ClearSelection()
SelectCells(hInfo.Band)
Else
Return
End If
CType(e, DXMouseEventArgs).Handled = True
End Sub
Private Sub SelectCells(ByVal column As BandedGridColumn)
For i As Integer = 0 To column.View.RowCount - 1
column.View.SelectCell(i, column)
Next i
End Sub
Private Sub SelectCells(ByVal band As GridBand)
For Each column As BandedGridColumn In band.Columns
SelectCells(column)
Next column
End Sub
I need GridView only, anyone can help?
If you want to use this code for GridView then you can just remove the word Banded from everywhere and remove anything that belongs to GridBand. For SelectedCells method you need to convert column.View to GridView. Also I suggest you to add GridView.BeginSelection and GridView.EndSelection methods into SelectedCells method.
Here is example:
Imports DevExpress.Utils
Imports DevExpress.XtraGrid.Columns
Imports DevExpress.XtraGrid.Views.Grid
Imports DevExpress.XtraGrid.Views.Grid.ViewInfo
'...
Private Sub gridView1_MouseDown(ByVal sender As Object, ByVal e As MouseEventArgs) Handles gridView1.MouseDown
If Control.ModifierKeys <> (Keys.Shift Or Keys.Control) Then
Return
End If
Dim view As GridView = CType(sender, GridView)
Dim hInfo As GridHitInfo = view.CalcHitInfo(e.Location)
If hInfo.InColumn Then
view.ClearSelection()
SelectCells(hInfo.Column)
Else
Return
End If
CType(e, DXMouseEventArgs).Handled = True
End Sub
Private Sub SelectCells(ByVal column As GridColumn)
Dim view As GridView = CType(column.View, GridView)
view.BeginSelection()
For i As Integer = 0 To view.RowCount - 1
view.SelectCell(i, column)
Next i
view.EndSelection()
End Sub