Imports DevExpress.XtraEditors Imports DevExpress.XtraGrid Imports DevExpress.XtraLayout Imports DigitalData.Modules.Logging Public Class frmObjectEditor 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 } If _Datatable Is Nothing Then ShowErrorMessage(New ArgumentNullException("Datatable is empty")) End If 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 GridControlDefaults.DefaultGridSettings). ProcessContainer(AddressOf GridControlDefaults.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 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 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 GetType(DateTime) Dim oDateEdit As New DateEdit() With { .Name = Column.ColumnName } oEditor = oDateEdit Case GetType(Boolean) Dim oCheckEdit = New CheckEdit() With { .Name = Column.ColumnName } oCheckEdit.Properties.Caption = Column.ColumnName oCheckEdit.Properties.GlyphAlignment = DevExpress.Utils.HorzAlignment.Far oEditor = oCheckEdit Case Else Dim oTextEdit = New MemoEdit() With { .Name = Column.ColumnName } oEditor = oTextEdit End Select Dim oMetadata As New ControlMetadata() With { .DataType = Column.DataType, .ColumnName = Column.ColumnName } ' Set EditControl Metadata If AttributeId = 0 Then oMetadata.AttributeId = Nothing Else oMetadata.AttributeId = AttributeId End If oEditor.Tag = oMetadata 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) ' Setup Databinding for editor If oColumn.DataType = GetType(Boolean) Then oEditor.DataBindings.Add(New Binding("Checked", _BindingSource, oColumn.ColumnName)) Else oEditor.DataBindings.Add(New Binding("Text", _BindingSource, oColumn.ColumnName)) End If ' 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 Private Sub ViewList_Layout(sender As Object, e As EventArgs) Handles ViewList.Layout End Sub End Class