Imports DevExpress.XtraEditors Imports DevExpress.XtraGrid Imports DevExpress.XtraLayout Imports DigitalData.Modules.Logging Public Class frmEdit Private ReadOnly _Datatable As DataTable Private _BindingSource As BindingSource Private _LayoutConfig As ClassUIConfig.EditFormConfig Private _LanguageDatatable As DataTable Private _AttributeId As Integer Private _Syskey As String Private Class ControlMetadata Public AttributeId As Integer Public DataType As Type Public ColumnName As String End Class Public Sub New(AttributeId As Integer, Syskey As String, Datatable As DataTable) ' Dieser Aufruf ist für den Designer erforderlich. InitializeComponent() ' Fügen Sie Initialisierungen nach dem InitializeComponent()-Aufruf hinzu. _Syskey = Syskey _AttributeId = AttributeId _Datatable = Datatable _BindingSource = New BindingSource With { .DataSource = _Datatable } End Sub Private Async Sub frmEdit_Load(sender As Object, e As EventArgs) Handles MyBase.Load Try Dim oGridPatcher = New ClassControlPatcher(Of GridControl)(Me) oGridPatcher. ProcessContainer(AddressOf ClassGridControl.DefaultGridSettings). ProcessContainer(AddressOf ClassGridControl.ReadOnlyGridSettings) labelParentAttributeId.Caption = $"Attribut-ID: {_AttributeId}" labelSyskey.Caption = $"Syskey: {_Syskey}" GridList.DataSource = _BindingSource _LayoutConfig = GetLayoutBySyskey(_Syskey) ApplyLayout() Await LoadLanguageTableAsync(My.Application.User.Language) LoadDetailForm() Catch ex As Exception _ErrorHandler.ShowErrorMessage(ex) End Try End Sub ''' ''' Applies to currently saved layout to all controls ''' Private Sub ApplyLayout() SplitContainer.Horizontal = _LayoutConfig.SplitterHorizontal SplitContainer.SplitterPosition = _LayoutConfig.SplitterDistance BarCheckHorizontalLayout.Checked = _LayoutConfig.SplitterHorizontal End Sub Private Function GetLayoutBySyskey(Syskey As String) As ClassUIConfig.EditFormConfig Dim oConfig = My.UIConfig.EditFormConfigs.Find(Function(c) c.SysKey = Syskey) If Not IsNothing(oConfig) Then Return oConfig Else Return New ClassUIConfig.EditFormConfig() With {.SysKey = Syskey} End If End Function Private Sub SaveLayoutBySyskey(Syskey As String, Config As ClassUIConfig.EditFormConfig) Dim oIndex = My.UIConfig.EditFormConfigs.FindIndex(Function(c) c.SysKey = Syskey) If oIndex >= 0 Then My.UIConfig.EditFormConfigs.Item(oIndex) = Config Else My.UIConfig.EditFormConfigs.Add(Config) End If My.UIConfigManager.Save() End Sub Private Sub ResetLayoutBySyskey(Syskey As String) Dim oIndex = My.UIConfig.EditFormConfigs.FindIndex(Function(c) c.SysKey = Syskey) Dim oDefaultLayout = New ClassUIConfig.EditFormConfig With {.SysKey = Syskey} If oIndex >= 0 Then My.UIConfig.EditFormConfigs.Item(oIndex) = oDefaultLayout End If My.UIConfigManager.Save() End Sub Private Async Function LoadLanguageTableAsync(UserLanguage As String) As Task Try Dim oSQL = $"SELECT * FROM VWICM_ATTRIBUTE_LANGUAGE WHERE LANGUAGE_CODE = '{UserLanguage}' AND PARENT_ATTRIBUTE_ID = '{_AttributeId}' ORDER BY ""SEQUENCE"";" Await My.Channel.CreateDatabaseRequestAsync("Language Syskey", False) Dim oResult = Await My.Channel.ReturnDatatableAsync(oSQL) _LanguageDatatable = oResult.Table Await My.Channel.CloseDatabaseRequestAsync() Catch ex As Exception _ErrorHandler.ShowErrorMessage(ex) End Try End Function Private Function GetColumnEditor(Column As DataColumn, AttributeId As Integer) Dim oEditor As BaseEdit Select Case Column.DataType Case GetType(Int64) Dim oIntegerEdit = New TextEdit() oIntegerEdit.Name = Column.ColumnName oIntegerEdit.Properties.Mask.MaskType = Mask.MaskType.Numeric oIntegerEdit.Properties.Mask.EditMask = "n" oEditor = oIntegerEdit Case Else oEditor = New TextEdit() With {.Name = Column.ColumnName} End Select ' Set EditControl Metadata If AttributeId > 0 Then oEditor.Tag = New ControlMetadata() With { .AttributeId = AttributeId, .DataType = Column.DataType, .ColumnName = Column.ColumnName } Else oEditor.Tag = New ControlMetadata() With { .AttributeId = Nothing, .DataType = Column.DataType, .ColumnName = Column.ColumnName } End If Return oEditor End Function Private Function GetColumnCaption(Column As DataColumn, SequenceId As Integer) Dim oRow = GetRowBySequence(SequenceId) Dim oCaption = Column.ColumnName If oRow IsNot Nothing Then oCaption = oRow.Item("LANGUAGE_TERM") ElseIf oCaption = ClassConstants.ATTRIBUTE_ID_COLUMN Then oCaption = "ID" End If Return oCaption End Function Private Function GetRowBySequence(SequenceId As Integer) Return _LanguageDatatable.Select($"SEQUENCE = {SequenceId}").FirstOrDefault() End Function Private Function GetRowItemBySequence(SequenceId As Integer, ColumnName As String) Dim oRow = _LanguageDatatable.Select($"SEQUENCE = {SequenceId}").FirstOrDefault() Return oRow?.Item(ColumnName) End Function Private Sub LoadDetailForm() ' Counter is used to match SEQUENCE in Attributes ' to column order in the used View (eg. VWICM_USER) Dim oCounter = 0 For Each oColumn As DataColumn In _Datatable.Columns Dim oAttributeId As Integer = GetRowItemBySequence(oCounter, "ATTRIBUTE_ID") Dim oCaption = GetColumnCaption(oColumn, oCounter) Dim oEditor = GetColumnEditor(oColumn, oAttributeId) oEditor.DataBindings.Add(New Binding("Text", _BindingSource, oColumn.ColumnName)) ' Add Control to Layout LayoutGroup.AddItem(oCaption, oEditor) ' Set Column Captions ViewList.Columns.Item(oColumn.ColumnName).Caption = oCaption oCounter = oCounter + 1 Next ' General Layout Tweaks LayoutGroup.AddItem(New EmptySpaceItem()) LayoutGroup.LayoutMode = Utils.LayoutMode.Flow End Sub Public Sub SaveRecord() _BindingSource.EndEdit() Dim oChanges As DataTable = _Datatable.GetChanges() Dim oChangedRow As DataRow = oChanges.Rows.Item(0) For Each oColumn As DataColumn In oChanges.Columns Dim oAttributeId = (From oItem As LayoutControlItem In LayoutGroup.Items Where oItem.Control.Name = oColumn.ColumnName Select DirectCast(oItem.Control.Tag, ControlMetadata).AttributeId).FirstOrDefault() Dim oValue = oChangedRow.Item(oColumn.ColumnName) MsgBox($"Saving Value {oValue} for Attribute {oAttributeId}") Next End Sub Private Sub SplitContainerControl1_SplitterPositionChanged(sender As Object, e As EventArgs) Handles SplitContainer.SplitterPositionChanged _LayoutConfig.SplitterDistance = SplitContainer.SplitterPosition SaveLayoutBySyskey(_Syskey, _LayoutConfig) End Sub Private Sub BarButtonSave_ItemClick(sender As Object, e As DevExpress.XtraBars.ItemClickEventArgs) Handles BarButtonSave.ItemClick SaveRecord() End Sub Private Sub BarCheckHorizontalLayout_CheckedChanged(sender As Object, e As DevExpress.XtraBars.ItemClickEventArgs) Handles BarCheckHorizontalLayout.CheckedChanged SplitContainer.Horizontal = BarCheckHorizontalLayout.Checked _LayoutConfig.SplitterHorizontal = BarCheckHorizontalLayout.Checked SaveLayoutBySyskey(_Syskey, _LayoutConfig) End Sub Private Sub BarButtonResetLayout_ItemClick(sender As Object, e As DevExpress.XtraBars.ItemClickEventArgs) Handles BarButtonResetLayout.ItemClick Dim oDefaultLayout = New ClassUIConfig.EditFormConfig With {.SysKey = _Syskey} SaveLayoutBySyskey(_Syskey, oDefaultLayout) _LayoutConfig = oDefaultLayout ApplyLayout() End Sub End Class