LookupGrid: Fix selecting checkboxes, fix possible crash with dbnull

This commit is contained in:
Jonathan Jenne 2022-03-24 11:22:47 +01:00
parent 684b3f63ac
commit 717bd506c5
3 changed files with 140 additions and 98 deletions

View File

@ -35,6 +35,34 @@ Public Class LookupControl3
Private Sub LookupControl3_EditValueChanging(sender As Object, e As ChangingEventArgs) Handles Me.EditValueChanging Private Sub LookupControl3_EditValueChanging(sender As Object, e As ChangingEventArgs) Handles Me.EditValueChanging
e.Cancel = True e.Cancel = True
End Sub End Sub
Friend WithEvents fProperties As RepositoryItemGridLookUpEdit
Friend WithEvents fPropertiesView As DevExpress.XtraGrid.Views.Grid.GridView
Private Sub InitializeComponent()
Me.fProperties = New DevExpress.XtraEditors.Repository.RepositoryItemGridLookUpEdit()
Me.fPropertiesView = New DevExpress.XtraGrid.Views.Grid.GridView()
CType(Me.fProperties, System.ComponentModel.ISupportInitialize).BeginInit()
CType(Me.fPropertiesView, System.ComponentModel.ISupportInitialize).BeginInit()
Me.SuspendLayout()
'
'fProperties
'
Me.fProperties.Buttons.AddRange(New DevExpress.XtraEditors.Controls.EditorButton() {New DevExpress.XtraEditors.Controls.EditorButton(DevExpress.XtraEditors.Controls.ButtonPredefines.Combo)})
Me.fProperties.Name = "fProperties"
Me.fProperties.PopupView = Me.fPropertiesView
'
'fPropertiesView
'
Me.fPropertiesView.FocusRectStyle = DevExpress.XtraGrid.Views.Grid.DrawFocusRectStyle.RowFocus
Me.fPropertiesView.Name = "fPropertiesView"
Me.fPropertiesView.OptionsSelection.EnableAppearanceFocusedCell = False
Me.fPropertiesView.OptionsView.ShowGroupPanel = False
CType(Me.fProperties, System.ComponentModel.ISupportInitialize).EndInit()
CType(Me.fPropertiesView, System.ComponentModel.ISupportInitialize).EndInit()
Me.ResumeLayout(False)
End Sub
End Class End Class
<UserRepositoryItem("RegisterLookupControl3")> <UserRepositoryItem("RegisterLookupControl3")>

View File

@ -1 +1,3 @@
DevExpress.XtraGrid.GridControl, DevExpress.XtraGrid.v21.2, Version=21.2.4.0, Culture=neutral, PublicKeyToken=b88d1754d700e49a DevExpress.XtraGrid.GridControl, DevExpress.XtraGrid.v21.2, Version=21.2.4.0, Culture=neutral, PublicKeyToken=b88d1754d700e49a
DevExpress.XtraEditors.Repository.RepositoryItemGridLookUpEdit, DevExpress.XtraGrid.v21.2, Version=21.2.4.0, Culture=neutral, PublicKeyToken=b88d1754d700e49a
DevExpress.XtraEditors.GridLookUpEdit, DevExpress.XtraGrid.v21.2, Version=21.2.4.0, Culture=neutral, PublicKeyToken=b88d1754d700e49a

View File

@ -22,6 +22,7 @@ Public Class frmLookupGrid
Private _Grid As GridControl Private _Grid As GridControl
Private ReadOnly _R As Resources.ResourceManager = My.Resources.Strings.ResourceManager Private ReadOnly _R As Resources.ResourceManager = My.Resources.Strings.ResourceManager
#Region "Form Events"
Private Sub frmLookupGrid_Load(sender As Object, e As EventArgs) Handles Me.Load Private Sub frmLookupGrid_Load(sender As Object, e As EventArgs) Handles Me.Load
_View = viewLookup _View = viewLookup
_Grid = gridLookup _Grid = gridLookup
@ -98,6 +99,112 @@ Public Class frmLookupGrid
Dim oDataColumn As GridColumn = _View.Columns.Item(_DataColumn) Dim oDataColumn As GridColumn = _View.Columns.Item(_DataColumn)
oDataColumn.BestFit() oDataColumn.BestFit()
End Sub End Sub
Private Sub frmLookupGrid_Shown(sender As Object, e As EventArgs) Handles Me.Shown
BringToFront()
End Sub
#End Region
#Region "Button Events"
Private Sub btnOK_Click(sender As Object, e As EventArgs) Handles btnOK.Click
SaveSelectedValues()
DialogResult = DialogResult.OK
Close()
End Sub
Private Sub btnClear_Click(sender As Object, e As EventArgs) Handles btnClear.Click
SelectedValues = New List(Of String)
DialogResult = DialogResult.OK
Close()
End Sub
#End Region
#Region "Grid Events"
Private Sub gridLookup_KeyUp(sender As Object, e As KeyEventArgs) Handles gridLookup.KeyUp
HandleCustomKeys(e)
End Sub
Private Sub gridLookup_EditorKeyUp(sender As Object, e As KeyEventArgs) Handles gridLookup.EditorKeyUp
HandleCustomKeys(e)
End Sub
Private Sub HandleCustomKeys(e As KeyEventArgs)
If e.KeyCode = Keys.Escape Then
Close()
ElseIf e.KeyCode = Keys.F2 Then
' Make sure the currently focused row's state is saved
viewLookup.PostEditor()
SaveSelectedValues()
DialogResult = DialogResult.OK
Close()
End If
End Sub
#End Region
#Region "View Events"
Private Sub viewLookup_ShowingEditor(sender As Object, e As System.ComponentModel.CancelEventArgs) Handles viewLookup.ShowingEditor
Dim rowHandleIsNewItemRow = (_View.FocusedRowHandle = GridControl.NewItemRowHandle)
Dim columnIsCheckboxColumn = (_View.FocusedColumn.FieldName = COLUMN_SELECTED)
' Prevent editing of Data Column/allow editing for Checkbox Column and NewValue Row
If rowHandleIsNewItemRow Or columnIsCheckboxColumn Then
e.Cancel = False
Else
e.Cancel = True
End If
End Sub
Private Sub viewLookup_RowClick(sender As Object, e As RowClickEventArgs) Handles viewLookup.RowClick
' If user double-clicks on a row
If e.Clicks = 2 And e.Button = MouseButtons.Left Then
' And clicked row is a normal row
If e.RowHandle >= 0 Then
' If multiselect is true, check the current row
' If multiselect is false, select the current row and close the window
If MultiSelect = True Then
Dim row As DataRow = _View.GetDataRow(e.RowHandle)
row.Item(0) = Not CBool(row.Item(0))
Else
Dim row As DataRow = _View.GetDataRow(e.RowHandle)
Dim value = row.Item(0)
SelectedValues = New List(Of String) From {value}
DialogResult = DialogResult.OK
Close()
End If
End If
End If
End Sub
Private Sub viewLookup_ValidateRow(sender As Object, e As ValidateRowEventArgs) Handles viewLookup.ValidateRow
If e.RowHandle = GridControl.NewItemRowHandle Then
Dim oRowView As DataRowView = viewLookup.GetRow(e.RowHandle)
Dim oValue = GetValueFromRow(oRowView.Row)
NewValues.Add(oValue)
' Automatically select newly added row when MultiSelect is enabled
If MultiSelect Then
oRowView.Row.Item(COLUMN_SELECTED) = True
End If
End If
End Sub
Private Sub viewLookup_RowCellClick(sender As Object, e As RowCellClickEventArgs) Handles viewLookup.RowCellClick
' When AllowFocus is used on the SELECTED Column, the checkbox can only be selected with a double click
' This function manually checks/unchecks the clicked cell
If MultiSelect AndAlso e.Column.FieldName = COLUMN_SELECTED Then
Dim row As DataRow = _View.GetDataRow(e.RowHandle)
row.Item(0) = Not CBool(row.Item(0))
End If
End Sub
Private Sub viewLookup_FocusedRowChanged(sender As Object, e As FocusedRowChangedEventArgs) Handles viewLookup.FocusedRowChanged
' Removed because it leads to some weird behaviour where you a locked in the new row forever
'If AddNewValues AndAlso e.PrevFocusedRowHandle = GridControl.NewItemRowHandle Then
' BeginInvoke(Sub() viewLookup.FocusedRowHandle = GridControl.NewItemRowHandle)
'End If
End Sub
#End Region
Private Sub SaveSelectedValues() Private Sub SaveSelectedValues()
' Filter vor dem Auslesen entfernen, damit alle Werte erfasst werden ' Filter vor dem Auslesen entfernen, damit alle Werte erfasst werden
@ -137,10 +244,11 @@ Public Class frmLookupGrid
End Sub End Sub
Private Function GetValueFromRow(pRow As DataRow) As String Private Function GetValueFromRow(pRow As DataRow) As String
' Converting to string explicitly to prevent DBNull crashing the function
If MultiSelect Then If MultiSelect Then
Return pRow.Item(1) Return pRow.Item(1).ToString()
Else Else
Return pRow.Item(0) Return pRow.Item(0).ToString()
End If End If
End Function End Function
@ -169,100 +277,4 @@ Public Class frmLookupGrid
End If End If
End Sub End Sub
Private Sub btnOK_Click(sender As Object, e As EventArgs) Handles btnOK.Click
SaveSelectedValues()
DialogResult = DialogResult.OK
Close()
End Sub
Private Sub btnClear_Click(sender As Object, e As EventArgs) Handles btnClear.Click
SelectedValues = New List(Of String)
DialogResult = DialogResult.OK
Close()
End Sub
Private Sub gridLookup_KeyUp(sender As Object, e As KeyEventArgs) Handles gridLookup.KeyUp
HandleCustomKeys(e)
End Sub
Private Sub gridLookup_EditorKeyUp(sender As Object, e As KeyEventArgs) Handles gridLookup.EditorKeyUp
HandleCustomKeys(e)
End Sub
Private Sub HandleCustomKeys(e As KeyEventArgs)
If e.KeyCode = Keys.Escape Then
Close()
ElseIf e.KeyCode = Keys.F2 Then
' Make sure the currently focused row's state is saved
viewLookup.PostEditor()
SaveSelectedValues()
DialogResult = DialogResult.OK
Close()
End If
End Sub
Private Sub viewLookup_ShowingEditor(sender As Object, e As System.ComponentModel.CancelEventArgs) Handles viewLookup.ShowingEditor
Dim rowHandleIsNewItemRow = (_View.FocusedRowHandle = GridControl.NewItemRowHandle)
Dim columnIsCheckboxColumn = (_View.FocusedColumn.FieldName = COLUMN_SELECTED)
' Prevent editing of Data Column/allow editing for Checkbox Column and NewValue Row
If rowHandleIsNewItemRow Or columnIsCheckboxColumn Then
e.Cancel = False
Else
e.Cancel = True
End If
End Sub
Private Sub viewLookup_RowClick(sender As Object, e As RowClickEventArgs) Handles viewLookup.RowClick
' If user double-clicks on a row
If e.Clicks = 2 And e.Button = MouseButtons.Left Then
' And clicked row is a normal row
If e.RowHandle >= 0 Then
' If multiselect is true, check the current row
' If multiselect is false, select the current row and close the window
If MultiSelect = True Then
Dim row As DataRow = _View.GetDataRow(e.RowHandle)
row.Item(0) = Not CBool(row.Item(0))
Else
Dim row As DataRow = _View.GetDataRow(e.RowHandle)
Dim value = row.Item(0)
SelectedValues = New List(Of String) From {value}
DialogResult = DialogResult.OK
Close()
End If
End If
End If
End Sub
Private Sub frmLookupGrid_Shown(sender As Object, e As EventArgs) Handles Me.Shown
BringToFront()
End Sub
Private Sub viewLookup_ValidateRow(sender As Object, e As ValidateRowEventArgs) Handles viewLookup.ValidateRow
If e.RowHandle = GridControl.NewItemRowHandle Then
Dim oRowView As DataRowView = viewLookup.GetRow(e.RowHandle)
Dim oValue = GetValueFromRow(oRowView.Row)
NewValues.Add(oValue)
' Automatically select newly added row when MultiSelect is enabled
If MultiSelect Then
oRowView.Row.Item(COLUMN_SELECTED) = True
End If
End If
End Sub
Private Sub viewLookup_FocusedRowChanged(sender As Object, e As FocusedRowChangedEventArgs) Handles viewLookup.FocusedRowChanged
' Removed because it leads to some weird behaviour where you a locked in the new row forever
'If AddNewValues AndAlso e.PrevFocusedRowHandle = GridControl.NewItemRowHandle Then
' BeginInvoke(Sub() viewLookup.FocusedRowHandle = GridControl.NewItemRowHandle)
'End If
End Sub
End Class End Class