Imports DevExpress.Utils
Imports DevExpress.XtraGrid
Imports DevExpress.XtraGrid.Columns
Imports DevExpress.XtraGrid.Views.Grid
Imports DevExpress.XtraEditors
Imports DevExpress.XtraEditors.Repository
Imports DevExpress.XtraGrid.Views.Base
Imports DevExpress.XtraEditors.Controls

Public Class ClassWindreamDocGrid
    ' === BEGIN CLASS PART ===

    Public Class WindreamDoc
        Public Property DocId As Integer
        Public Property DocPath As String
        Public Property DisplayName As String
        Public Property DocType As String
    End Class

    Private ReadOnly GridView As GridView

    Public ReadOnly Property SelectedDocuments As List(Of WindreamDoc)
        Get
            Return GetSelectedDocuments(GridView)
        End Get
    End Property

    Public ReadOnly Property HasSelectedDocuments As Boolean
        Get
            Return HasNoSelectedDocuments(GridView)
        End Get
    End Property

    Public Sub New(pGridView As GridView)
        GridView = pGridView
    End Sub

    ' === END CLASS PART ===

    Private Shared _Helper As ClassHelper
    Public Shared SELECTED_DOC_PATH As String
    'Public Shared RESULT_OBJECTTYPE As String
    Public Shared SELECTED_INWORK As Boolean
    Public Shared SELECTED_DOC_ID As Integer
    Public Shared SELECTED_DOC_RIGHT As Integer
    'Public Shared RESULT_DISPLAYNAME As String
    Public Shared RESULT_CONFIG_IDS As Hashtable
    Private Shared ReadOnly DATE_COLUMNS As New List(Of String)
    Private Shared ReadOnly DATE_COLUMNS_CONFIG As New List(Of String)

    ' This should replace DT_RESULTFILES and also
    ' SELECTED_INWORK, SELECTED_DOC_ID, SELECTED_DOC_RIGHT, SELECTED_DOC_PATH
    Public Shared SELECTED_DOCUMENTS As New List(Of WindreamDoc)

    Public Shared DT_RESULTFILES As DataTable
    Private Shared DT_DROPDOWN_ITEMS As DataTable

    Private Shared _dropdownValueChangedHandler As EventHandler
    Private Shared _datepickerValueChangedHandler As EventHandler
    Private Shared _textValueChangedHandler As EventHandler
    Private Shared _checkValueChangedHandler As EventHandler

    Private Shared Function Init_Table()
        Try
            Dim table As New DataTable With {
                .TableName = "TBSELECTED_FILES"
            }

            ' Create two columns, ID and Name.
            table.Columns.Add("DOC_ID", GetType(Integer))
            table.Columns.Add("DOC_PATH", GetType(System.String))
            table.Columns.Add("OBJECTTYPE", GetType(System.String))
            table.Columns.Add("INWORK", GetType(System.Boolean))
            table.Columns.Add("DISPLAYNAME", GetType(System.String))
            table.Columns.Add("ACCESS_RIGHT", GetType(Integer))
            DT_RESULTFILES = table
            Return True
        Catch ex As Exception
            LOGGER.Warn("Unexpected Error in Initting TableResult Docs: " & ex.Message)
            DT_RESULTFILES = Nothing
            Return False
        End Try

    End Function

    Public Shared Function HasNoSelectedDocuments(pGridView As GridView) As Boolean
        Dim oSelectedRows As List(Of Integer) = pGridView.GetSelectedRows().ToList()
        Return oSelectedRows.Count = 0
    End Function

    Public Shared Function GetSelectedDocuments(pGridView As GridView) As List(Of WindreamDoc)
        Dim oSelectedRows As List(Of Integer) = pGridView.GetSelectedRows().ToList()
        Dim oDocuments As New List(Of WindreamDoc)

        For Each oRowHandle In oSelectedRows
            Dim oDocId = pGridView.GetRowCellValue(oRowHandle, "DocID")
            Dim oDisplayName = pGridView.GetRowCellValue(oRowHandle, "Displayname")
            Dim oDocPath = pGridView.GetRowCellValue(oRowHandle, "FULLPATH")
            Dim oDocType = pGridView.GetRowCellValue(oRowHandle, "OBJECTTYPE")

            oDocuments.Add(New WindreamDoc With {
                .DocId = oDocId,
                .DocPath = oDocPath,
                .DocType = oDocType,
                .DisplayName = oDisplayName
            })
        Next

        Return oDocuments
    End Function

    Public Shared Sub GetDocItems(gridView As GridView)
        _Helper = New ClassHelper
        SELECTED_DOC_ID = 0
        If Init_Table() = True Then
            Console.WriteLine("gridView.SelectedRowsCount: " & gridView.SelectedRowsCount.ToString)
            gridView.EndSelection()

            If gridView.SelectedRowsCount >= 1 Then
                DT_RESULTFILES.Clear()
                For Each row In gridView.GetSelectedRows
                    Dim newRow As DataRow = DT_RESULTFILES.NewRow()
                    Try
                        Dim DOC_ID = gridView.GetRowCellValue(row, "DocID")
                        Dim CHeckDT As DataTable = ClassHelper.FILTER_DATATABLE(CURRENT_DT_TBPMO_DOC_RECORD_LINK, "DOC_ID = " + DOC_ID.ToString, "")
                        If CHeckDT.Rows.Count = 1 Then
                            SELECTED_DOC_ID = DOC_ID
                            newRow("DOC_ID") = gridView.GetRowCellValue(row, "DocID")
                        Else
                            Continue For
                        End If

                    Catch ex As Exception
                        newRow("DOC_ID") = 0
                        SELECTED_DOC_ID = 0
                    End Try

                    Try
                        newRow("INWORK") = False
                        SELECTED_INWORK = False
                        Dim oSQL = "Select IN_WORK,IN_WORK_USER FROM TBPMO_DOCRESULT_LIST  where DocID = " + SELECTED_DOC_ID
                        Dim oDT As DataTable = MYDB_ECM.GetDatatable(oSQL)
                        If Not IsNothing(oDT) Then
                            If oDT.Rows.Count = 1 Then
                                newRow("INWORK") = CBool(oDT.Rows(0).Item("IN_WORK"))
                                SELECTED_INWORK = CBool(oDT.Rows(0).Item("IN_WORK"))
                            End If
                        End If
                    Catch ex As Exception
                        newRow("INWORK") = False
                        SELECTED_INWORK = False
                    End Try

                    Try
                        SELECTED_DOC_RIGHT = gridView.GetRowCellValue(row, "ACCESS_RIGHT")
                        newRow("ACCESS_RIGHT") = gridView.GetRowCellValue(row, SELECTED_DOC_RIGHT)
                    Catch ex As Exception
                        newRow("ACCESS_RIGHT") = 1
                    End Try
                    Try
                        SELECTED_DOC_PATH = _Helper.FORMAT_WM_PATH(gridView.GetRowCellValue(row, "FULLPATH"))
                        newRow("DOC_PATH") = gridView.GetRowCellValue(row, "FULLPATH")
                    Catch ex As Exception
                        newRow("DOC_PATH") = ""
                    End Try
                    Try
                        newRow("OBJECTTYPE") = gridView.GetRowCellValue(row, "OBJECTTYPE")
                    Catch ex As Exception
                        newRow("OBJECTTYPE") = ""
                    End Try

                    Try
                        Dim dpn = gridView.GetRowCellValue(row, "Displayname")
                        If IsDBNull(dpn) Or IsNothing(dpn) Then
                            dpn = ""
                        End If
                        newRow("DISPLAYNAME") = dpn
                    Catch ex As Exception
                        newRow("DISPLAYNAME") = ""
                    End Try
                    DT_RESULTFILES.Rows.Add(newRow)
                    DT_RESULTFILES.AcceptChanges()
                Next
            Else
                Dim newRow As DataRow = DT_RESULTFILES.NewRow()
                Try
                    Dim DOC_ID = gridView.GetFocusedRowCellValue(gridView.Columns("DocID"))
                    SELECTED_DOC_ID = DOC_ID
                    newRow("DOC_ID") = gridView.GetFocusedRowCellValue(gridView.Columns("DocID"))
                Catch ex As Exception
                    newRow("DOC_ID") = 0
                    SELECTED_DOC_ID = 0
                End Try
                Try
                    SELECTED_DOC_PATH = gridView.GetFocusedRowCellValue(gridView.Columns("FULLPATH"))
                    If IsNothing(SELECTED_DOC_PATH) Then
                        SELECTED_DOC_PATH = gridView.GetFocusedRowCellValue(gridView.Columns("FULL_FILENAME"))
                        newRow("DOC_PATH") = gridView.GetFocusedRowCellValue(gridView.Columns("FULL_FILENAME"))
                    Else
                        newRow("DOC_PATH") = gridView.GetFocusedRowCellValue(gridView.Columns("FULLPATH"))
                    End If

                Catch ex As Exception
                    Try

                    Catch ex1 As Exception
                        newRow("DOC_PATH") = ""
                    End Try

                End Try
                Try
                    newRow("OBJECTTYPE") = gridView.GetFocusedRowCellValue(gridView.Columns("OBJECTTYPE"))
                Catch ex As Exception
                    newRow("OBJECTTYPE") = ""
                End Try

                Try
                    Dim dpn = gridView.GetFocusedRowCellValue(gridView.Columns("Displayname"))
                    If IsDBNull(dpn) Or IsNothing(dpn) Then
                        dpn = ""
                    End If
                    newRow("DISPLAYNAME") = dpn
                Catch ex As Exception
                    newRow("DISPLAYNAME") = ""
                End Try
                DT_RESULTFILES.Rows.Add(newRow)
                DT_RESULTFILES.AcceptChanges()
            End If
        End If
    End Sub

    Public Shared Sub FillColumns(gridView As GridView,
                                  DT_RESULT As DataTable, DT_WINDREAM_RESULTLIST As DataTable, DT_DOCRESULT_DROPDOWN_ITEMS As DataTable,
                                  DropdownValueChangedHandler As EventHandler, DatepickerValueChangedHandler As EventHandler, TextValueChangedHandler As EventHandler, CheckValueChangedHandler As EventHandler,
                                  SearchType As String, RECORD_ID As Integer)
        ' Handler speichern
        _dropdownValueChangedHandler = DropdownValueChangedHandler
        _datepickerValueChangedHandler = DatepickerValueChangedHandler
        _textValueChangedHandler = TextValueChangedHandler
        _checkValueChangedHandler = CheckValueChangedHandler

        'Dropdown Tabelle speichern
        DT_DROPDOWN_ITEMS = DT_DOCRESULT_DROPDOWN_ITEMS

        ' Tabelle vor dem verändern klonen
        Dim clonedTable As DataTable = DT_RESULT.Clone()

        RESULT_CONFIG_IDS = New Hashtable()

        For Each row As DataRow In DT_WINDREAM_RESULTLIST.Rows
            Dim isConfig As Boolean = row.Item("CONFIG_COLUMNS")
            Dim guid As Integer = row.Item("GUID")
            Dim columnTitle As String = row.Item("HEADER_CAPTION")
            Dim type As Integer = row.Item("TYPE_ID")


            If type = 3 And isConfig = False Then
                DATE_COLUMNS.Add(columnTitle)
            ElseIf type = 3 And isConfig = True Then
                DATE_COLUMNS_CONFIG.Add(columnTitle)
            End If

            If isConfig = True Then
                RESULT_CONFIG_IDS.Add(columnTitle, guid)
            End If
        Next

        ' Tabelle zurückspielen und zuweisen
        Try
            clonedTable.Load(DT_RESULT.CreateDataReader())
            DT_RESULT = clonedTable

            ' Neues Dataset für Master- und Detail-Tabelle erstellen
            Dim ds As New DataSet()
            Dim DT_DETAILS_SQL

            Select Case CURRENT_SEARCH_TYPE
                Case "NODE_DOWN"
                    DT_DETAILS_SQL = String.Format("SELECT T.[GUID],T.[DocID],T.[CONFIG_ID],T1.HEADER_CAPTION,T.[VALUE],T1.[LANGUAGE], T1.COLUMN_VIEW,T1.EDITABLE,T1.TYPE_ID,T1.VISIBLE,T.CHANGED_WHEN,T.CHANGED_WHO " &
                                               "FROM TBPMO_DOC_VALUES T INNER JOIN TBPMO_STRUCTURE_NODES_USER_TEMP TTEMP ON T.RECORD_ID = TTEMP.RECORD_ID RIGHT JOIN TBPMO_DOCSEARCH_RESULTLIST_CONFIG T1 ON T.CONFIG_ID = T1.GUID WHERE T1.ENTITY_ID = {0} AND LANGUAGE = '{1}' AND T1.CONFIG_COLUMNS = 1", CURRENT_ENTITY_ID, USER_LANGUAGE)

                Case Else
                    DT_DETAILS_SQL = String.Format("SELECT T.[GUID],T.[DocID],T.[CONFIG_ID],T1.HEADER_CAPTION,T.[VALUE],T1.[LANGUAGE], T1.COLUMN_VIEW,T1.EDITABLE,T1.TYPE_ID,T1.VISIBLE,T.CHANGED_WHEN,T.CHANGED_WHO " &
                                               "FROM TBPMO_DOC_VALUES T RIGHT JOIN TBPMO_DOCSEARCH_RESULTLIST_CONFIG T1 ON T.CONFIG_ID = T1.GUID WHERE T1.ENTITY_ID = {0} AND LANGUAGE = '{1}' AND T1.CONFIG_COLUMNS = 1 AND T.RECORD_ID = {2}", CURRENT_ENTITY_ID, USER_LANGUAGE, RECORD_ID)

            End Select
            '"FROM TBPMO_DOC_VALUES T INNER JOIN TBPMO_DOCSEARCH_RESULTLIST_CONFIG T1 ON T.CONFIG_ID = T1.GUID WHERE T1.ENTITY_ID = {0} AND T1.LANGUAGE = '{1}' AND T.RECORD_ID = {2} ORDER BY T.DocID, T1.SEQUENCE", CURRENT_ENTITY_ID, USER_LANGUAGE, RECORD_ID)

            Dim DT_DETAILS As DataTable = MYDB_ECM.GetDatatable(DT_DETAILS_SQL)
            Dim docId As Integer
            Dim configId As Integer
            Dim recordId As Integer
            Try
                ' Werte für Konfigurierte Spalten aus TBPMO_DOC_VALUES auslesen und Zellenweise einfügen
                For Each row As DataRow In DT_RESULT.Rows
                    For Each col As DataColumn In DT_RESULT.Columns
                        Dim colName As String = col.ColumnName
                        docId = row.Item("DocID")
                        configId = RESULT_CONFIG_IDS.Item(col.ColumnName)

                        If configId <> 0 Then
                            Dim value As String = ""

                            Try
                                value = MYDB_ECM.GetScalarValue(String.Format("SELECT VALUE FROM TBPMO_DOC_VALUES WHERE CONFIG_ID = {0} AND DocID = {1} AND RECORD_ID = {2}", configId, docId, RECORD_ID))
                            Catch ex As Exception
                                LOGGER.Warn(String.Format("Attention: Could not get Value from TBPMO_DOC_VALUES for ConfigId[{0}], DocId[{1}]: ", configId, docId) & ex.Message)
                            End Try

                            row.Item(colName) = value
                        End If
                    Next
                Next
            Catch ex As Exception
                LOGGER.Warn($"Attention: Could not load values from TBPMO_DOC_VALUES: " & ex.Message & vbNewLine & $"SELECT VALUE FROM TBPMO_DOC_VALUES WHERE CONFIG_ID = {configId} AND DocID = {docId} AND RECORD_ID = {RECORD_ID}")
            End Try
            LOGGER.Debug("Values loaded...")
            Try
                ' Tabellen zum DataSet hinzufügen
                ds.Tables.Add(DT_RESULT)
                ds.Tables.Add(DT_DETAILS)
                LOGGER.Debug("tables added to ds.Tables...")
            Catch ex As Exception
                LOGGER.Warn("Attention: Could not Add tables to ds.Tables: " & ex.Message)
            End Try

            Try
                Dim resultTable As DataTable = ds.Tables(0)
                Dim detailsTable As DataTable = ds.Tables(1)

                ' Relation `docIdDetails` erstellen
                Dim parentColumn As DataColumn = resultTable.Columns("docId")
                Dim childColumn As DataColumn = detailsTable.Columns("docId")

                ' Unique Constraint für DT_RESULT auf Spalte `docId` erstellen
                Dim uniqueConstraint As UniqueConstraint = New UniqueConstraint(parentColumn)
                resultTable.Constraints.Add(uniqueConstraint)

                ' Parameter `createConstraints` auf false setzen, um erstellung eines unsinnigen
                ' `foreignKeyConstraints` zu verhindern
                ds.Relations.Add("docIdDetails", parentColumn, childColumn, False)
                LOGGER.Debug("relationdocIdDetails created...")
            Catch ex As Exception
                LOGGER.Warn("Could not set master-detail Relation DocSearch: " & ex.Message)
            End Try

            Dim gridControl As GridControl = gridView.GridControl


            ' Datasource auf Master-Tabelle setzen
            'gridView.GridControl.DataSource = DT_RESULT
            gridControl.DataSource = ds.Tables(0)
            gridControl.ForceInitialize()

            ' Detail View anlegen und der Relation `docIdDetails` zuweisen
            Dim grvwDetail As New GridView(gridControl)
            'grvwDetail.OptionsBehavior.Editable = False
            grvwDetail.OptionsView.ShowGroupPanel = False
            grvwDetail.BorderStyle = DevExpress.XtraEditors.Controls.BorderStyles.Style3D
            grvwDetail.OptionsView.EnableAppearanceEvenRow = True
            grvwDetail.Appearance.EvenRow.BackColor = Color.Orange
            grvwDetail.Appearance.HeaderPanel.BackColor = Color.Orange
            grvwDetail.Appearance.HeaderPanel.Options.UseBackColor = True


            gridControl.LevelTree.Nodes.Add("docIdDetails", grvwDetail)
        Catch ex As Exception
            MsgBox("Error in FillColumns: " & vbNewLine & ex.Message, MsgBoxStyle.Critical)
            LOGGER.Warn("Attention: Could not load converted datatable DocSearch: " & ex.Message)
        End Try

        AddHandler gridView.MasterRowExpanded, AddressOf gridView_MasterRowExpanded
        AddHandler gridView.CustomColumnDisplayText, AddressOf gridView_CustomColumnDisplayText


        For Each row As DataRow In DT_WINDREAM_RESULTLIST.Rows
            Dim col As GridColumn = gridView.Columns(row.Item("HEADER_CAPTION"))
            Dim colCaption = row.Item("HEADER_CAPTION")
            Dim type As Integer = row.Item("TYPE_ID")
            Dim isConfig As Boolean = row.Item("CONFIG_COLUMNS")

            If Not IsNothing(col) And type = 3 And isConfig Then
                LOGGER.Debug($"Adapting DisplayFormat (DATETIME for Column {colCaption}")
                col.DisplayFormat.FormatType = FormatType.DateTime
                col.DisplayFormat.FormatString = CURRENT_DATE_FORMAT & " HH:MM:ss"
            End If
        Next

        gridView.Columns.Item("ICON").MaxWidth = 24
        gridView.Columns.Item("ICON").MinWidth = 24
        gridView.Columns.Item("FULLPATH").Visible = False
        gridView.Columns.Item("OBJECTTYPE").Visible = False
        If Not System.IO.File.Exists(LAYOUT_DOC_GRIDVIEW) Then
            gridView.Columns.Item("DocID").Visible = False
        End If

        Dim oCreatedFieldName, oChangedFieldName As String
        If USER_LANGUAGE <> "de-DE" Then
            oChangedFieldName = "Changed"
            oCreatedFieldName = "Created"
        Else
            oChangedFieldName = "Geändert"
            oCreatedFieldName = "Erstellt"
        End If

        Dim oCreatedColumn = gridView.Columns(oCreatedFieldName)
        If Not IsNothing(oCreatedColumn) Then
            oCreatedColumn.DisplayFormat.FormatType = FormatType.DateTime
            oCreatedColumn.DisplayFormat.FormatString = CURRENT_DATE_FORMAT & " HH:MM:ss"
        End If

        Dim oChangedColumn = gridView.Columns(oChangedFieldName)
        If Not IsNothing(oChangedColumn) Then
            oChangedColumn.DisplayFormat.FormatType = FormatType.DateTime
            oChangedColumn.DisplayFormat.FormatString = CURRENT_DATE_FORMAT & " HH:MM:ss"
        End If

        If GridDocResult_BestFitColumns Then
            gridView.OptionsView.BestFitMaxRowCount = -1
            gridView.BestFitColumns(True)
        End If

        ' Alle Spalten aus ReadOnly setzen, danach werden alle passenden auf nicht ReadOnly gesetzt
        For Each column As GridColumn In gridView.Columns
            column.OptionsColumn.AllowEdit = False
        Next
    End Sub

    Public Shared Sub detailView_CustomRowCellEdit(grvw As GridView, e As CustomRowCellEditEventArgs)
        Try
            If (e.Column.Name = "colVALUE") Then
                Dim rowView As DataRowView = grvw.GetRow(e.RowHandle)
                Dim configId As Integer = rowView.Item("CONFIG_ID")
                Dim title = rowView.Item("HEADER_CAPTION")
                Dim editable As Boolean = rowView.Item("EDITABLE")
                Dim typeId As Integer = rowView.Item("TYPE_ID")

                If typeId = 1 And editable Then
                    Dim textedit As New RepositoryItemTextEdit()

                    AddHandler textedit.Leave, _textValueChangedHandler

                    e.RepositoryItem = textedit
                ElseIf typeId = 2 Then
                    Dim checkEdit As New RepositoryItemCheckEdit()
                    checkEdit.ValueChecked = "True"
                    checkEdit.ValueUnchecked = "False"
                    checkEdit.GlyphAlignment = HorzAlignment.Near
                    checkEdit.Caption = String.Empty

                    AddHandler checkEdit.CheckedChanged, _checkValueChangedHandler

                    e.RepositoryItem = checkEdit
                ElseIf typeId = 3 Then
                    Dim dateedit As New RepositoryItemDateEdit()

                    dateedit.DisplayFormat.FormatType = FormatType.DateTime
                    dateedit.DisplayFormat.FormatString = CURRENT_DATE_FORMAT
                    dateedit.EditFormat.FormatType = FormatType.DateTime
                    dateedit.EditFormat.FormatString = CURRENT_DATE_FORMAT
                    dateedit.EditMask = CURRENT_DATE_FORMAT

                    AddHandler dateedit.FormatEditValue, Sub(sender As Object, _e As ConvertEditValueEventArgs)
                                                             _e.Handled = True
                                                         End Sub

                    AddHandler dateedit.CustomDisplayText, Sub(sender As Object, _e As Controls.CustomDisplayTextEventArgs)
                                                               Dim parsedDate As DateTime
                                                               Dim stringDate As String = _e.Value.ToString
                                                               If stringDate.Trim() = String.Empty Then
                                                                   _e.DisplayText = ""
                                                               Else
                                                                   If Not DateTime.TryParse(stringDate, parsedDate) Then
                                                                       parsedDate = DateTime.ParseExact(stringDate, CURRENT_DATE_FORMAT, Globalization.DateTimeFormatInfo.InvariantInfo)
                                                                   End If
                                                                   _e.DisplayText = parsedDate.ToString(CURRENT_DATE_FORMAT)
                                                               End If
                                                           End Sub

                    AddHandler dateedit.EditValueChanged, _datepickerValueChangedHandler
                    e.RepositoryItem = dateedit
                ElseIf typeId = 10 And editable = True Then
                    Dim dropdown As New RepositoryItemComboBox()
                    Dim matchingRows() As DataRow = DT_DROPDOWN_ITEMS.Select(String.Format("CONFIG_ID = {0}", configId), "SEQUENCE")

                    For Each matchingRow As DataRow In matchingRows
                        Dim item As New WindreamDocGridComboboxItem()
                        item.ConfigID = matchingRow.Item("CONFIG_ID")
                        item.Value = matchingRow.Item("VALUE")
                        dropdown.Items.Add(item)
                    Next

                    AddHandler dropdown.SelectedValueChanged, _dropdownValueChangedHandler

                    e.RepositoryItem = dropdown


                ElseIf typeId = 4 And editable Then
                    Dim textedit As New RepositoryItemTextEdit()

                    AddHandler textedit.Leave, _textValueChangedHandler

                    e.RepositoryItem = textedit

                End If
            ElseIf (e.Column.Name <> "colVALUE") Then
                ' Erlaube Editieren nur für VALUE Spalte
                e.Column.OptionsColumn.AllowEdit = False
            End If
        Catch ex As Exception
            LOGGER.Warn("Error in detailView_CustomRowCellEdit: " & ex.Message)
        End Try

    End Sub

    Private Shared Sub gridView_CustomColumnDisplayText(sender As Object, e As CustomColumnDisplayTextEventArgs)
        Try
            Dim view As ColumnView = sender
            Dim parsedDate As DateTime
            If Not IsNothing(DATE_COLUMNS) Then
                If DATE_COLUMNS.Contains(e.Column.FieldName) And e.ListSourceRowIndex <> DevExpress.XtraGrid.GridControl.InvalidRowHandle Then
                    LOGGER.Debug($"gridView_CustomColumnDisplayText1 [{e.Column.FieldName}] ")
                    If e.Value.ToString() = String.Empty Then
                        e.DisplayText = ""
                        Exit Sub
                    End If

                    If Not DateTime.TryParse(e.Value, parsedDate) Then
                        parsedDate = DateTime.ParseExact(e.Value, CURRENT_DATE_FORMAT & " HH:MM:ss", System.Globalization.DateTimeFormatInfo.InvariantInfo)
                    End If

                    e.DisplayText = parsedDate.ToString(CURRENT_DATE_FORMAT & " HH:MM:ss")

                End If
            End If
            If Not IsNothing(DATE_COLUMNS_CONFIG) Then
                If DATE_COLUMNS_CONFIG.Contains(e.Column.FieldName) And e.ListSourceRowIndex <> DevExpress.XtraGrid.GridControl.InvalidRowHandle Then
                    If e.Value.ToString() = String.Empty Then
                        e.DisplayText = ""
                        Exit Sub
                    End If
                    LOGGER.Debug($"gridView_CustomColumnDisplayText2 [{e.Column.FieldName}] ")
                    If Not DateTime.TryParse(e.Value, parsedDate) Then
                        parsedDate = DateTime.ParseExact(e.Value, CURRENT_DATE_FORMAT, System.Globalization.DateTimeFormatInfo.InvariantInfo)
                    End If

                    e.DisplayText = parsedDate.ToString(CURRENT_DATE_FORMAT)
                End If
            End If
        Catch ex As Exception
            LOGGER.Warn("Unexpected error in gridView_CustomColumnDisplayText: " & ex.Message)
        End Try

    End Sub

    Public Shared Sub gridView_MasterRowExpanded(sender As GridView, e As DevExpress.XtraGrid.Views.Grid.CustomMasterRowEventArgs)
        Try
            ClassWindreamDocGrid.GetDocItems(sender)
            Dim GW As GridView = sender
            If SELECTED_DOC_ID = 0 Then
                MsgBox("Sorry no document was selected! Please try again!", MsgBoxStyle.Exclamation)
                Exit Sub
            End If

            Dim detailView As GridView = sender.GetDetailView(e.RowHandle, e.RelationIndex)
            With detailView.Columns
                'Spalten ausblenden
                .Item("GUID").Visible = False
                .Item("DocID").Visible = False
                .Item("CONFIG_ID").Visible = False
                .Item("LANGUAGE").Visible = False
                .Item("COLUMN_VIEW").Visible = False
                .Item("EDITABLE").Visible = False
                .Item("TYPE_ID").Visible = False
                .Item("VISIBLE").Visible = False

                'Spalten formatieren

                .Item("CHANGED_WHEN").DisplayFormat.FormatType = FormatType.DateTime
                .Item("CHANGED_WHEN").DisplayFormat.FormatString = CURRENT_DATE_FORMAT & " HH:MM:ss"

                If USER_LANGUAGE = "de-DE" Then
                    .Item("HEADER_CAPTION").Caption = "Beschreibung"
                    .Item("VALUE").Caption = "Wert"
                    .Item("CHANGED_WHEN").Caption = "Geändert Wann"
                    .Item("CHANGED_WHO").Caption = "Geändert Wer"
                Else
                    .Item("HEADER_CAPTION").Caption = "Description"
                    .Item("VALUE").Caption = "Value"
                    .Item("CHANGED_WHEN").Caption = "Changed when"
                    .Item("CHANGED_WHO").Caption = "changed Who"
                End If
            End With
            If Not IsNothing(GW.GridControl.ContextMenuStrip.Name) Then
                If GW.GridControl.ContextMenuStrip.Name = "cmsResultFilesBasic" Then
                    detailView.OptionsBehavior.Editable = False
                Else
                    detailView.OptionsBehavior.Editable = True
                End If
            End If
            AddHandler detailView.CustomRowCellEdit, AddressOf detailView_CustomRowCellEdit
        Catch ex As Exception
            LOGGER.Warn("Unexpected error in gridView_MasterRowExpanded: " & ex.Message)
            MsgBox("Unexpected error in gridView_MasterRowExpanded: " & ex.Message, MsgBoxStyle.Critical)
        End Try

    End Sub

    Public Class WindreamDocGridComboboxItem
        Implements IConvertible

        Public ConfigID As Integer
        Public Value As String

        Public Overrides Function ToString() As String
            Return Me.Value
        End Function

        Public Function ToString1(provider As IFormatProvider) As String Implements IConvertible.ToString
            Return Me.Value
        End Function

        Public Function GetTypeCode() As TypeCode Implements IConvertible.GetTypeCode
            Throw New NotImplementedException
        End Function

        Public Function ToBoolean(provider As IFormatProvider) As Boolean Implements IConvertible.ToBoolean
            Throw New NotImplementedException
        End Function

        Public Function ToByte(provider As IFormatProvider) As Byte Implements IConvertible.ToByte
            Throw New NotImplementedException
        End Function

        Public Function ToChar(provider As IFormatProvider) As Char Implements IConvertible.ToChar
            Throw New NotImplementedException
        End Function

        Public Function ToDateTime(provider As IFormatProvider) As Date Implements IConvertible.ToDateTime
            Throw New NotImplementedException
        End Function

        Public Function ToDecimal(provider As IFormatProvider) As Decimal Implements IConvertible.ToDecimal
            Throw New NotImplementedException
        End Function

        Public Function ToDouble(provider As IFormatProvider) As Double Implements IConvertible.ToDouble
            Throw New NotImplementedException
        End Function

        Public Function ToInt16(provider As IFormatProvider) As Short Implements IConvertible.ToInt16
            Throw New NotImplementedException
        End Function

        Public Function ToInt32(provider As IFormatProvider) As Integer Implements IConvertible.ToInt32
            Throw New NotImplementedException
        End Function

        Public Function ToInt64(provider As IFormatProvider) As Long Implements IConvertible.ToInt64
            Throw New NotImplementedException
        End Function

        Public Function ToSByte(provider As IFormatProvider) As SByte Implements IConvertible.ToSByte
            Throw New NotImplementedException
        End Function

        Public Function ToSingle(provider As IFormatProvider) As Single Implements IConvertible.ToSingle
            Throw New NotImplementedException
        End Function

        Public Function ToType(conversionType As Type, provider As IFormatProvider) As Object Implements IConvertible.ToType
            Throw New NotImplementedException
        End Function

        Public Function ToUInt16(provider As IFormatProvider) As UShort Implements IConvertible.ToUInt16
            Throw New NotImplementedException
        End Function

        Public Function ToUInt32(provider As IFormatProvider) As UInteger Implements IConvertible.ToUInt32
            Throw New NotImplementedException
        End Function

        Public Function ToUInt64(provider As IFormatProvider) As ULong Implements IConvertible.ToUInt64
            Throw New NotImplementedException
        End Function
    End Class

End Class
