From 717bd506c5097f85cbabd8dc3bc0ad24b8e5e439 Mon Sep 17 00:00:00 2001 From: Jonathan Jenne Date: Thu, 24 Mar 2022 11:22:47 +0100 Subject: [PATCH] LookupGrid: Fix selecting checkboxes, fix possible crash with dbnull --- Controls.LookupGrid/LookupControl3.vb | 28 ++++ Controls.LookupGrid/My Project/licenses.licx | 2 + Controls.LookupGrid/frmLookupGrid.vb | 168 ++++++++++--------- 3 files changed, 120 insertions(+), 78 deletions(-) diff --git a/Controls.LookupGrid/LookupControl3.vb b/Controls.LookupGrid/LookupControl3.vb index bfafd11c..14e052e2 100644 --- a/Controls.LookupGrid/LookupControl3.vb +++ b/Controls.LookupGrid/LookupControl3.vb @@ -35,6 +35,34 @@ Public Class LookupControl3 Private Sub LookupControl3_EditValueChanging(sender As Object, e As ChangingEventArgs) Handles Me.EditValueChanging e.Cancel = True 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 diff --git a/Controls.LookupGrid/My Project/licenses.licx b/Controls.LookupGrid/My Project/licenses.licx index 887f6738..0321d5c5 100644 --- a/Controls.LookupGrid/My Project/licenses.licx +++ b/Controls.LookupGrid/My Project/licenses.licx @@ -1 +1,3 @@ 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 diff --git a/Controls.LookupGrid/frmLookupGrid.vb b/Controls.LookupGrid/frmLookupGrid.vb index 2f0b2a40..d028376a 100644 --- a/Controls.LookupGrid/frmLookupGrid.vb +++ b/Controls.LookupGrid/frmLookupGrid.vb @@ -22,6 +22,7 @@ Public Class frmLookupGrid Private _Grid As GridControl 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 _View = viewLookup _Grid = gridLookup @@ -98,77 +99,11 @@ Public Class frmLookupGrid Dim oDataColumn As GridColumn = _View.Columns.Item(_DataColumn) oDataColumn.BestFit() End Sub - - Private Sub SaveSelectedValues() - ' Filter vor dem Auslesen entfernen, damit alle Werte erfasst werden - _View.FindFilterText = String.Empty - - If MultiSelect Then - Dim oValues As New List(Of String) - - For oIndex = 0 To viewLookup.DataRowCount - 1 - Dim oRow As DataRow = _View.GetDataRow(oIndex) - Dim oSelected As Boolean = oRow.Item(0) - Dim oValue As Object = GetValueFromRow(oRow) - - If oSelected Then - oValues.Add(oValue) - End If - Next - - ' Doppelte Werte entfernen, wenn konfiguriert - If PreventDuplicates Then - oValues = oValues.Distinct().ToList() - End If - - SelectedValues = oValues - Else - Dim oRowHandle As Integer = _View.GetSelectedRows().ToList().FirstOrDefault() - Dim oRow As DataRow = _View.GetDataRow(oRowHandle) - Dim oValues As New List(Of String) - - If oRow IsNot Nothing Then - Dim oValue = GetValueFromRow(oRow) - oValues.Add(oValue) - End If - - SelectedValues = oValues - End If - End Sub - - Private Function GetValueFromRow(pRow As DataRow) As String - If MultiSelect Then - Return pRow.Item(1) - Else - Return pRow.Item(0) - End If - End Function - - Private Sub SyncItemsWithView(view As GridView) - ' Wenn Vorbelegungen existieren, werden diese angehakt - If SelectedValues.Count > 0 Then - For i = 0 To view.DataRowCount - 1 - Dim rowHandle = view.GetRowHandle(i) - Dim rowView As DataRowView = view.GetRow(rowHandle) - - If rowView IsNot Nothing Then - Dim row As DataRow = rowView.Row - Dim value = row.Item(_DataColumn) - - If Not (IsDBNull(value) OrElse String.IsNullOrWhiteSpace(value)) Then - If SelectedValues.Contains(value) Then - If MultiSelect Then - row.Item(0) = True - Else - view.SelectRow(rowHandle) - End If - End If - End If - End If - Next - End If + 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() @@ -182,7 +117,8 @@ Public Class frmLookupGrid 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 @@ -204,7 +140,8 @@ Public Class frmLookupGrid 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) @@ -240,10 +177,6 @@ Public Class frmLookupGrid 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) @@ -257,12 +190,91 @@ Public Class frmLookupGrid 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() + ' Filter vor dem Auslesen entfernen, damit alle Werte erfasst werden + _View.FindFilterText = String.Empty + + If MultiSelect Then + Dim oValues As New List(Of String) + + For oIndex = 0 To viewLookup.DataRowCount - 1 + Dim oRow As DataRow = _View.GetDataRow(oIndex) + Dim oSelected As Boolean = oRow.Item(0) + Dim oValue As Object = GetValueFromRow(oRow) + + If oSelected Then + oValues.Add(oValue) + End If + Next + + ' Doppelte Werte entfernen, wenn konfiguriert + If PreventDuplicates Then + oValues = oValues.Distinct().ToList() + End If + + SelectedValues = oValues + Else + Dim oRowHandle As Integer = _View.GetSelectedRows().ToList().FirstOrDefault() + Dim oRow As DataRow = _View.GetDataRow(oRowHandle) + Dim oValues As New List(Of String) + + If oRow IsNot Nothing Then + Dim oValue = GetValueFromRow(oRow) + oValues.Add(oValue) + End If + + SelectedValues = oValues + End If + End Sub + + Private Function GetValueFromRow(pRow As DataRow) As String + ' Converting to string explicitly to prevent DBNull crashing the function + If MultiSelect Then + Return pRow.Item(1).ToString() + Else + Return pRow.Item(0).ToString() + End If + End Function + + Private Sub SyncItemsWithView(view As GridView) + ' Wenn Vorbelegungen existieren, werden diese angehakt + If SelectedValues.Count > 0 Then + For i = 0 To view.DataRowCount - 1 + Dim rowHandle = view.GetRowHandle(i) + Dim rowView As DataRowView = view.GetRow(rowHandle) + + If rowView IsNot Nothing Then + Dim row As DataRow = rowView.Row + Dim value = row.Item(_DataColumn) + + If Not (IsDBNull(value) OrElse String.IsNullOrWhiteSpace(value)) Then + If SelectedValues.Contains(value) Then + If MultiSelect Then + row.Item(0) = True + Else + view.SelectRow(rowHandle) + End If + End If + End If + End If + Next + End If + End Sub + End Class \ No newline at end of file