482 lines
24 KiB
VB.net
482 lines
24 KiB
VB.net
Imports DevExpress.Utils
|
|
Imports DevExpress.XtraEditors
|
|
Imports DevExpress.XtraEditors.Repository
|
|
Imports DevExpress.XtraGrid.Columns
|
|
Imports DevExpress.XtraGrid.Views.Grid
|
|
Imports DigitalData.Controls.LookupGrid
|
|
Imports DigitalData.Modules.EDMI.API.Constants
|
|
Imports DigitalData.Modules.EDMI.API.DatabaseWithFallback
|
|
Imports DigitalData.Modules.Logging
|
|
Imports DigitalData.Modules.Base
|
|
Imports System.ComponentModel
|
|
Imports DevExpress.XtraEditors.Controls
|
|
Imports DevExpress.XtraGrid.Views.Base
|
|
Imports System.Text.RegularExpressions
|
|
Imports System.Globalization
|
|
Imports DevExpress.Xpo.Helpers.AssociatedCollectionCriteriaHelper
|
|
Imports DevExpress.XtraEditors.Mask
|
|
|
|
Namespace ControlCreator
|
|
Public Class GridControl
|
|
Private ReadOnly _LogConfig As LogConfig
|
|
Private ReadOnly _Logger As Logger
|
|
Private ReadOnly _GridTables As Dictionary(Of Integer, Dictionary(Of String, RepositoryItem))
|
|
|
|
Private newRowModified As Boolean
|
|
|
|
Public Sub New(pLogConfig As LogConfig, pGridTables As Dictionary(Of Integer, Dictionary(Of String, RepositoryItem)))
|
|
_LogConfig = pLogConfig
|
|
_Logger = pLogConfig.GetLogger()
|
|
_GridTables = pGridTables
|
|
End Sub
|
|
|
|
Public Function CreateGridColumns(pColumnTable As DataTable) As DataTable
|
|
Dim oDataTable As New DataTable
|
|
|
|
For Each oRow As DataRow In pColumnTable.Rows
|
|
' Create Columns in Datatable
|
|
|
|
Dim oColumn = New DataColumn() With {
|
|
.ColumnName = oRow.Item("SPALTENNAME"),
|
|
.Caption = oRow.Item("SPALTEN_HEADER_LANG"),
|
|
.ReadOnly = False
|
|
}
|
|
Select Case oRow.Item("TYPE_COLUMN")
|
|
Case Constants.CONTROL_TYPE_TEXT
|
|
oColumn.DataType = GetType(String)
|
|
Case Constants.CONTROL_TYPE_INTEGER
|
|
oColumn.DataType = GetType(Integer)
|
|
Case Constants.CONTROL_TYPE_DOUBLE
|
|
oColumn.DataType = GetType(Double)
|
|
Case Constants.CONTROL_TYPE_CURRENCY
|
|
oColumn.DataType = GetType(Double)
|
|
Case Constants.CONTROL_TYPE_BOOLEAN
|
|
oColumn.DataType = GetType(Boolean)
|
|
Case Else
|
|
oColumn.DataType = GetType(String)
|
|
End Select
|
|
|
|
oDataTable.Columns.Add(oColumn)
|
|
Next
|
|
|
|
Return oDataTable
|
|
End Function
|
|
|
|
Public Function FillGridTables(pColumnTable As DataTable, pControlId As Integer, pControlName As String) As Dictionary(Of Integer, Dictionary(Of String, RepositoryItem))
|
|
For Each oRow As DataRow In pColumnTable.Rows
|
|
' Fetch and cache Combobox results
|
|
Dim oConnectionId As Integer = oRow.ItemEx("CONNECTION_ID", 0)
|
|
Dim oSqlCommand As String = oRow.ItemEx("SQL_COMMAND", "")
|
|
|
|
If oConnectionId > 0 And oSqlCommand <> "" Then
|
|
Try
|
|
Dim oComboboxDataTable As DataTable = Nothing
|
|
Dim oColumnName As String = oRow.Item("SPALTENNAME")
|
|
_Logger.Debug("Working on SQL for Column[{0}]...", oColumnName)
|
|
If Not clsPatterns.HasComplexPatterns(oSqlCommand) Then
|
|
_Logger.Debug("SQL has no complex patterns!")
|
|
'oComboboxDataTable = ClassDatabase.Return_Datatable_ConId(oSqlCommand, oConnectionId)
|
|
oComboboxDataTable = DatabaseFallback.GetDatatable(New GetDatatableOptions(oSqlCommand, DatabaseType.ECM) With {
|
|
.ConnectionId = oConnectionId
|
|
})
|
|
Else
|
|
_Logger.Debug("...has complex patterns!!")
|
|
End If
|
|
|
|
Dim oRepositoryItem = GridTables_GetRepositoryItemForColumn(oColumnName, oComboboxDataTable, oRow.Item("ADVANCED_LOOKUP"))
|
|
|
|
If _GridTables.Item(pControlId).ContainsKey(oColumnName) Then
|
|
_GridTables.Item(pControlId).Item(oColumnName) = oRepositoryItem
|
|
Else
|
|
_GridTables.Item(pControlId).Add(oColumnName, oRepositoryItem)
|
|
End If
|
|
Catch ex As Exception
|
|
_Logger.Warn("Could not load data for column {0} in control {1}", oRow.Item("SPALTENNAME"), pControlName)
|
|
_Logger.Error(ex)
|
|
End Try
|
|
End If
|
|
Next
|
|
|
|
Return _GridTables
|
|
End Function
|
|
|
|
Private Function GridTables_GetRepositoryItemForColumn(pColumnName As String, pDataTable As DataTable, pIsAdvancedLookup As Boolean) As RepositoryItem
|
|
If pIsAdvancedLookup Then
|
|
|
|
Dim oEditor = New RepositoryItemLookupControl3
|
|
|
|
If pDataTable IsNot Nothing Then
|
|
oEditor.DisplayMember = pDataTable.Columns.Item(0).ColumnName
|
|
oEditor.ValueMember = pDataTable.Columns.Item(0).ColumnName
|
|
oEditor.DataSource = pDataTable
|
|
End If
|
|
|
|
Return oEditor
|
|
Else
|
|
Dim oEditor = New RepositoryItemComboBox()
|
|
Dim oItems As New List(Of String)
|
|
|
|
AddHandler oEditor.Validating, Sub(_sender As ComboBoxEdit, _e As CancelEventArgs)
|
|
If oItems.Contains(_sender.EditValue) Then
|
|
_e.Cancel = False
|
|
Else
|
|
_e.Cancel = True
|
|
End If
|
|
|
|
End Sub
|
|
|
|
If pDataTable IsNot Nothing Then
|
|
For Each oRow2 As DataRow In pDataTable.Rows
|
|
Dim oValue = oRow2.Item(0)
|
|
|
|
Try
|
|
If oRow2.ItemArray.Length > 1 Then
|
|
oValue &= $" | {oRow2.Item(1)}"
|
|
End If
|
|
Catch ex As Exception
|
|
End Try
|
|
|
|
oEditor.Items.Add(oValue)
|
|
oItems.Add(oValue)
|
|
Next
|
|
End If
|
|
|
|
Return oEditor
|
|
End If
|
|
End Function
|
|
|
|
Public Sub ConfigureViewColumns(pColumnTable As DataTable, pGridView As GridView, pGrid As DevExpress.XtraGrid.GridControl)
|
|
Dim oShouldDisplayFooter As Boolean = False
|
|
|
|
|
|
|
|
For Each oCol As GridColumn In pGridView.Columns
|
|
Dim oColumnData As DataRow = pColumnTable.
|
|
Select($"SPALTENNAME = '{oCol.FieldName}'").
|
|
FirstOrDefault()
|
|
|
|
If oColumnData Is Nothing Then
|
|
Continue For
|
|
End If
|
|
|
|
Dim oSequence As Integer = oColumnData.Item("SEQUENCE")
|
|
oCol.VisibleIndex = oSequence
|
|
|
|
Dim oColumnType As String = oColumnData.Item("TYPE_COLUMN")
|
|
|
|
Select Case oColumnType
|
|
Case "INTEGER"
|
|
oCol.DisplayFormat.FormatType = FormatType.Custom
|
|
oCol.DisplayFormat.FormatString = "N0"
|
|
|
|
Case "DOUBLE"
|
|
oCol.DisplayFormat.FormatType = FormatType.Custom
|
|
oCol.DisplayFormat.FormatString = "N2"
|
|
|
|
Case "CURRENCY"
|
|
oCol.DisplayFormat.FormatType = FormatType.Custom
|
|
oCol.DisplayFormat.FormatString = "C2"
|
|
End Select
|
|
|
|
Dim oSummaryFunction As String = oColumnData.Item("SUMMARY_FUNCTION")
|
|
|
|
Select Case oSummaryFunction
|
|
Case Constants.AGGREGATE_TOTAL_INTEGER
|
|
oCol.SummaryItem.SummaryType = DevExpress.Data.SummaryItemType.Sum
|
|
oCol.SummaryItem.DisplayFormat = "SUM: {0:N0}"
|
|
oShouldDisplayFooter = True
|
|
|
|
Case Constants.AGGREGATE_TOTAL_FLOAT
|
|
oCol.SummaryItem.SummaryType = DevExpress.Data.SummaryItemType.Sum
|
|
oCol.SummaryItem.DisplayFormat = "SUM: {0:N2}"
|
|
oShouldDisplayFooter = True
|
|
|
|
Case Constants.AGGREGATE_TOTAL_CURRENCY
|
|
oCol.SummaryItem.SummaryType = DevExpress.Data.SummaryItemType.Sum
|
|
oCol.SummaryItem.DisplayFormat = "SUM: {0:C2}"
|
|
oShouldDisplayFooter = True
|
|
|
|
Case Constants.AGGREGATE_TOTAL_AVG
|
|
oCol.SummaryItem.SummaryType = DevExpress.Data.SummaryItemType.Average
|
|
oCol.SummaryItem.DisplayFormat = "AVG: {0}"
|
|
oShouldDisplayFooter = True
|
|
|
|
Case Constants.AGGREGATE_TOTAL_MAX
|
|
oCol.SummaryItem.SummaryType = DevExpress.Data.SummaryItemType.Max
|
|
oCol.SummaryItem.DisplayFormat = "MAX: {0}"
|
|
oShouldDisplayFooter = True
|
|
|
|
Case Constants.AGGREGATE_TOTAL_MIN
|
|
oCol.SummaryItem.SummaryType = DevExpress.Data.SummaryItemType.Min
|
|
oCol.SummaryItem.DisplayFormat = "MIN: {0}"
|
|
oShouldDisplayFooter = True
|
|
|
|
Case Constants.AGGREGATE_TOTAL_COUNT
|
|
oCol.SummaryItem.SummaryType = DevExpress.Data.SummaryItemType.Count
|
|
oCol.SummaryItem.DisplayFormat = "NUM: {0}"
|
|
oShouldDisplayFooter = True
|
|
|
|
End Select
|
|
Next
|
|
|
|
pGridView.OptionsView.ShowFooter = oShouldDisplayFooter
|
|
End Sub
|
|
Public Sub ConfigureViewColumnsCurrency(pColumnTable As DataTable, pGridView As GridView, pGrid As DevExpress.XtraGrid.GridControl, pCurrency As String)
|
|
|
|
Dim oCultureInfo As CultureInfo = New CultureInfo("de-DE")
|
|
oCultureInfo.NumberFormat.CurrencySymbol = pCurrency
|
|
Dim riTextEdit As RepositoryItemTextEdit = New RepositoryItemTextEdit()
|
|
riTextEdit.MaskSettings.Configure(Of MaskSettings.Numeric)(Sub(settings)
|
|
settings.MaskExpression = "c"
|
|
settings.Culture = oCultureInfo
|
|
End Sub)
|
|
riTextEdit.UseMaskAsDisplayFormat = True 'Optional
|
|
pGrid.RepositoryItems.Add(riTextEdit)
|
|
|
|
|
|
For Each oCol As GridColumn In pGridView.Columns
|
|
Dim oColumnData As DataRow = pColumnTable.
|
|
Select($"SPALTENNAME = '{oCol.FieldName}'").
|
|
FirstOrDefault()
|
|
|
|
If oColumnData Is Nothing Then
|
|
Continue For
|
|
End If
|
|
|
|
Dim oColumnType As String = oColumnData.Item("TYPE_COLUMN")
|
|
|
|
Select Case oColumnType
|
|
Case "CURRENCY"
|
|
oCol.DisplayFormat.FormatType = FormatType.Custom
|
|
oCol.ColumnEdit = riTextEdit
|
|
End Select
|
|
|
|
Next
|
|
End Sub
|
|
Public Sub ConfigureViewEvents(pColumnTable As DataTable, pGridView As GridView, pControl As Windows.Forms.Control, pControlId As Integer)
|
|
AddHandler pGridView.InitNewRow, Sub(sender As Object, e As InitNewRowEventArgs)
|
|
Try
|
|
_Logger.Debug("Initialzing new row")
|
|
|
|
For Each oColumnData As DataRow In pColumnTable.Rows
|
|
For Each oGridColumn As GridColumn In pGridView.Columns
|
|
If oGridColumn.FieldName <> oColumnData.Item("SPALTENNAME") Then
|
|
Continue For
|
|
End If
|
|
|
|
Dim oDefaultValue = ObjectEx.NotNull(oColumnData.Item("DEFAULT_VALUE"), String.Empty)
|
|
|
|
If oDefaultValue <> String.Empty Then
|
|
_Logger.Debug("Setting default value [{0}] for column [{1}]", oDefaultValue, oGridColumn.FieldName)
|
|
pGridView.SetRowCellValue(e.RowHandle, oGridColumn.FieldName, oDefaultValue)
|
|
End If
|
|
Next
|
|
Next
|
|
|
|
Catch ex As Exception
|
|
_Logger.Error(ex)
|
|
Finally
|
|
newRowModified = False
|
|
End Try
|
|
End Sub
|
|
|
|
AddHandler pGridView.CustomRowCellEdit, Sub(sender As Object, e As CustomRowCellEditEventArgs)
|
|
Try
|
|
For Each oRow As DataRow In pColumnTable.Rows
|
|
Dim oColumnName = oRow.Item("SPALTENNAME")
|
|
Dim oEditorExists = GridTables_TestEditorExistsByControlAndColumn(pControlId, oColumnName)
|
|
If oColumnName <> e.Column.FieldName Then
|
|
Continue For
|
|
End If
|
|
|
|
If oEditorExists Then
|
|
Dim oEditor = _GridTables.Item(pControlId).Item(oColumnName)
|
|
_Logger.Debug("Assigning Editor to Column [{0}]", oColumnName)
|
|
e.RepositoryItem = oEditor
|
|
Else
|
|
_Logger.Debug("Editor for Column [{0}] does not exist", oColumnName)
|
|
End If
|
|
Next
|
|
Catch ex As Exception
|
|
_Logger.Warn("Error in CustomRowCellEdit for [{0}]", e.CellValue)
|
|
_Logger.Error(ex)
|
|
End Try
|
|
End Sub
|
|
|
|
AddHandler pGridView.ValidatingEditor, Sub(sender As Object, e As BaseContainerValidateEditorEventArgs)
|
|
Dim oRow As DataRowView = pGridView.GetRow(pGridView.FocusedRowHandle)
|
|
Dim oColumnName = pGridView.FocusedColumn.FieldName
|
|
_Logger.Debug("Validating Editor for Column [{0}]", oColumnName)
|
|
GridTables_ValidateColumn(pGridView, pColumnTable, oColumnName, e.Value, e.Valid, e.ErrorText)
|
|
End Sub
|
|
|
|
AddHandler pGridView.PopupMenuShowing, AddressOf View_PopupMenuShowing
|
|
|
|
AddHandler pGridView.InvalidRowException, AddressOf View_InvalidRowException
|
|
AddHandler pGridView.ValidatingEditor, AddressOf View_ValidatingEditor
|
|
' AddHandler pGridView.CustomColumnDisplayText, AddressOf View_CustomColumnDisplayText
|
|
|
|
' These handlers are all used for the custom DefaultValue functionality, additionally some code in the 'InitNewRow' event.
|
|
' https://supportcenter.devexpress.com/ticket/details/t1035580/how-to-default-a-value-in-a-column-when-add-new-row-in-data-grid
|
|
AddHandler pGridView.ShowingEditor, AddressOf View_ShowingEditor
|
|
AddHandler pGridView.ShownEditor, AddressOf View_ShownEditor
|
|
AddHandler pGridView.ValidateRow, AddressOf View_ValidateRow
|
|
AddHandler pControl.LostFocus, AddressOf Control_LostFocus
|
|
End Sub
|
|
Private Sub View_CustomColumnDisplayText(ByVal eSender As Object, ByVal e As CustomColumnDisplayTextEventArgs)
|
|
If IsNothing(e.Value) Then
|
|
Exit Sub
|
|
End If
|
|
Dim view As GridView = eSender
|
|
'Dim view As GridView = TryCast(GridView1, GridView)
|
|
If e.Column.FieldName = "SpalteCurrency" Then
|
|
' e.DisplayText = e.Value.ToString().Replace("€", "CHF")
|
|
End If
|
|
End Sub
|
|
Private Sub View_PopupMenuShowing(sender As Object, e As PopupMenuShowingEventArgs)
|
|
Dim view As GridView = TryCast(sender, GridView)
|
|
Dim oFocusedColumn As GridColumn = view.FocusedColumn
|
|
Dim oColumnType As Type = oFocusedColumn.ColumnType
|
|
Dim oColumnName As String = oFocusedColumn.FieldName
|
|
|
|
If e.MenuType = GridMenuType.Column AndAlso oColumnType Is GetType(Boolean) Then
|
|
e.Menu.Items.Add(New Menu.DXMenuItem(
|
|
"Alle Zeilen anhaken",
|
|
Sub(_sender As Object, _e As EventArgs)
|
|
SetCellValuesForBooleanColumn(view, oColumnName, True)
|
|
End Sub,
|
|
My.Resources.itemtypechecked,
|
|
Menu.DXMenuItemPriority.Normal))
|
|
|
|
e.Menu.Items.Add(New Menu.DXMenuItem(
|
|
"Alle Zeilen abhaken",
|
|
Sub(_sender As Object, _e As EventArgs)
|
|
SetCellValuesForBooleanColumn(view, oColumnName, False)
|
|
End Sub,
|
|
My.Resources.itemtypechecked,
|
|
Menu.DXMenuItemPriority.Normal))
|
|
End If
|
|
End Sub
|
|
|
|
Private Sub SetCellValuesForBooleanColumn(pView As GridView, pColumnName As String, pValue As Boolean)
|
|
Dim oRowHandle = 0
|
|
While (pView.IsValidRowHandle(oRowHandle))
|
|
Dim oRow = pView.GetDataRow(oRowHandle)
|
|
Dim oValue = oRow.ItemEx(pColumnName, False)
|
|
oRow.Item(pColumnName) = pValue
|
|
|
|
oRowHandle += 1
|
|
End While
|
|
End Sub
|
|
|
|
|
|
Private Sub Control_LostFocus(sender As DevExpress.XtraGrid.GridControl, e As EventArgs)
|
|
Dim oView2 As GridView = sender.FocusedView
|
|
|
|
' 19.08.2022:
|
|
' Calling UpdateCurrentRow when newRowModified Is true
|
|
' leads to some weird jumping of focus in the current cell.
|
|
' This seems to fix it.
|
|
If newRowModified = False Then
|
|
oView2.UpdateCurrentRow()
|
|
End If
|
|
End Sub
|
|
|
|
Private Sub View_ShowingEditor(sender As Object, e As CancelEventArgs)
|
|
Dim view As GridView = TryCast(sender, GridView)
|
|
_Logger.Debug("Showing editor.")
|
|
If view.IsNewItemRow(view.FocusedRowHandle) AndAlso Not newRowModified Then
|
|
_Logger.Debug("Adding new row.")
|
|
view.AddNewRow()
|
|
End If
|
|
End Sub
|
|
|
|
Private Sub View_ShownEditor(sender As Object, e As EventArgs)
|
|
Dim view As GridView = TryCast(sender, GridView)
|
|
If view.IsNewItemRow(view.FocusedRowHandle) Then
|
|
_Logger.Debug("Attaching Modified Handler.")
|
|
AddHandler view.ActiveEditor.Modified, Sub()
|
|
_Logger.Debug("Row was modified.")
|
|
newRowModified = True
|
|
End Sub
|
|
End If
|
|
End Sub
|
|
|
|
Private Sub View_ValidateRow(sender As Object, e As ValidateRowEventArgs)
|
|
Dim view As GridView = TryCast(sender, GridView)
|
|
If view.IsNewItemRow(e.RowHandle) AndAlso Not newRowModified Then
|
|
_Logger.Debug("Deleting unused row")
|
|
view.DeleteRow(e.RowHandle)
|
|
End If
|
|
|
|
_Logger.Debug("Validating row. Resetting Modified.")
|
|
newRowModified = False
|
|
End Sub
|
|
|
|
Private Sub View_ValidatingEditor(sender As Object, e As BaseContainerValidateEditorEventArgs)
|
|
Dim oValue As String = ObjectEx.NotNull(e.Value, "")
|
|
|
|
If oValue.Contains(" | ") Then
|
|
oValue = oValue.Split(" | ").ToList().First()
|
|
e.Value = oValue
|
|
End If
|
|
End Sub
|
|
|
|
Private Sub View_InvalidRowException(sender As Object, e As InvalidRowExceptionEventArgs)
|
|
e.ExceptionMode = ExceptionMode.NoAction
|
|
End Sub
|
|
|
|
Private Function GridTables_TestEditorExistsByControlAndColumn(oControlId As Integer, pColumn As String) As Boolean
|
|
If _GridTables.ContainsKey(oControlId) Then
|
|
Dim oContainsKey = _GridTables.Item(oControlId).ContainsKey(pColumn)
|
|
If oContainsKey AndAlso _GridTables.Item(oControlId).Item(pColumn) IsNot Nothing Then
|
|
Return True
|
|
Else
|
|
Return False
|
|
End If
|
|
Else
|
|
Return False
|
|
End If
|
|
End Function
|
|
|
|
Private Function GridTables_ValidateColumn(pView As GridView, pColumnDefinition As DataTable, ColumnName As String, pValue As Object, ByRef pIsValid As Boolean, ByRef pErrorText As String) As Boolean
|
|
Dim oColumn As DataRow = (From r As DataRow In pColumnDefinition.Rows
|
|
Where r.Item("SPALTENNAME") = ColumnName
|
|
Select r).FirstOrDefault()
|
|
|
|
Dim oGridColumn As GridColumn = (From c As GridColumn In pView.Columns
|
|
Where c.FieldName = ColumnName
|
|
Select c).FirstOrDefault()
|
|
|
|
Dim oIsRequired = oColumn.Item("VALIDATION")
|
|
|
|
Try
|
|
Dim oRegex = ObjectEx.NotNull(oColumn.Item("REGEX_MATCH"), String.Empty)
|
|
Dim oRegexMessage = ObjectEx.NotNull(oColumn.Item("REGEX_MESSAGE_DE"), String.Empty)
|
|
If oRegex <> String.Empty Then
|
|
Dim oMatch = New Regex(oRegex).IsMatch(pValue.ToString)
|
|
Dim oDefaultMessage = "Wert entspricht nicht dem gefordertem Format!"
|
|
Dim oMessage = IIf(oRegexMessage <> String.Empty, oRegexMessage, oDefaultMessage)
|
|
|
|
If oMatch = False Then
|
|
pErrorText = oMessage
|
|
pIsValid = False
|
|
Return False
|
|
End If
|
|
End If
|
|
Catch ex As Exception
|
|
_Logger.Error(ex)
|
|
End Try
|
|
|
|
If oIsRequired And (pValue IsNot Nothing AndAlso pValue.ToString = "") Then
|
|
pErrorText = "Spalte muss ausgefüllt werden!"
|
|
pIsValid = False
|
|
Return False
|
|
|
|
End If
|
|
|
|
Return True
|
|
End Function
|
|
End Class
|
|
End Namespace
|