Files
TaskFlow/app/TaskFlow/frmControl_Table.vb
2026-06-24 15:24:15 +02:00

607 lines
25 KiB
VB.net

Imports System.Data
Imports System.Globalization
Imports DevExpress.Data
Imports DevExpress.Utils
Imports DevExpress.XtraEditors
Imports DevExpress.XtraExport.Helpers
Imports DevExpress.XtraGrid
Imports DevExpress.XtraGrid.Columns
Imports DevExpress.XtraGrid.Views.Base
Imports DevExpress.XtraGrid.Views.Grid
Imports DevExpress.XtraReports.ReportGeneration
Imports DigitalData.Modules.Logging
Imports DigitalData.Modules.EDMI.API
Public Class frmControl_Table
Private _gridControl As GridControl
Private _gridView As GridView
Private _controlRow As DataRow
Private _dataTable As DataTable
Private _docCurrency As String
Private _profilID As Integer
Private _controlID As Integer
Private _parentValidator As frmValidator
Private _controlCreator As ClassControlCreator
Private ReadOnly MyControlTableLogger As Logger
Private _gridDataLoader As ClassGridDataLoader
Private _isDirty As Boolean = False
' Öffentliche Property für Dirty-Status
Public ReadOnly Property IsDirty As Boolean
Get
Return _isDirty
End Get
End Property
Public Sub New(controlRow As DataRow, dataTable As DataTable, docCurrency As String, parentValidator As frmValidator, controlCreator As ClassControlCreator)
InitializeComponent()
MyControlTableLogger = LOGCONFIG.GetLogger()
_gridDataLoader = New ClassGridDataLoader(DatabaseFallback)
_controlRow = controlRow
_dataTable = dataTable
_docCurrency = docCurrency
_parentValidator = parentValidator
_controlCreator = controlCreator
If controlRow IsNot Nothing Then
_profilID = If(IsDBNull(controlRow("PROFIL_ID")), 0, CInt(controlRow("PROFIL_ID")))
_controlID = If(IsDBNull(controlRow("GUID")), 0, CInt(controlRow("GUID")))
Dim oTitle = $"TABLE.{controlRow("NAME")}.FORMCAPTION"
Dim oCaption = ClassAllgemeineFunktionen.GUI_LANGUAGE_INFO(oTitle)
If IsNothing(oCaption) Then
Me.Text = controlRow("CTRL_TEXT").ToString()
Else
Me.Text = oCaption
End If
End If
End Sub
Private Function GetXML_FormSizeName(pProfilID As Integer, pControlID As Integer)
Dim Filename As String = String.Format($"Formlayout_{pProfilID}-{pControlID}.xml")
Return System.IO.Path.Combine(USER_CONFIG_DIRECTORY, Filename)
End Function
Public Function GetGridControl() As GridControl
Return _gridControl
End Function
Private Sub frmControl_Table_Load(sender As Object, e As EventArgs) Handles MyBase.Load
Try
MyControlTableLogger?.Debug("=== FORM LOAD START ===")
MyControlTableLogger?.Debug($"Form Size: {Me.Size}, Controls vor Grid: {Me.Controls.Count}")
' Grid über ControlCreator erstellen (wie im frmValidator)
CreateGridViaControlCreator()
' WICHTIG: Grid-Daten befüllen
FillGridWithData()
MyControlTableLogger?.Debug($"Nach CreateGrid - Controls im Form: {Me.Controls.Count}")
' GridControl-Status prüfen
If _gridControl IsNot Nothing Then
MyControlTableLogger?.Debug($"GridControl.Visible: {_gridControl.Visible}, Enabled: {_gridControl.Enabled}")
MyControlTableLogger?.Debug($"GridControl.Size: {_gridControl.Size}, Location: {_gridControl.Location}")
MyControlTableLogger?.Debug($"GridControl.Parent: {_gridControl.Parent?.Name}")
End If
' Formular-Größe wiederherstellen
RestoreFormSize()
MyControlTableLogger?.Debug("=== FORM LOAD END ===")
Catch ex As Exception
MyControlTableLogger?.Error($"Fehler beim Laden des Grids: {ex.Message}", ex)
XtraMessageBox.Show($"Fehler beim Laden des Grids: {ex.Message}", "Fehler", MessageBoxButtons.OK, MessageBoxIcon.Error)
End Try
End Sub
''' <summary>
''' Befüllt das Grid mit Daten aus der Datenbank
''' </summary>
Private Sub FillGridWithData()
Try
If _gridControl Is Nothing OrElse _parentValidator Is Nothing Then
MyControlTableLogger?.Warn("FillGridWithData: GridControl oder ParentValidator ist Nothing")
Return
End If
MyControlTableLogger?.Debug("Starte FillGridWithData...")
' ✅ RICHTIG: DT_COLUMNS_GRID (ALLE Spalten mit SPALTENBREITE!)
Dim allColumnDefinitions As DataTable = _parentValidator.DT_COLUMNS_GRID
If allColumnDefinitions Is Nothing Then
MyControlTableLogger?.Warn("Keine Spalten-Definitionen verfügbar (DT_COLUMNS_GRID)")
Return
End If
Dim isIDBActive As Boolean = IDB_ACTIVE
Dim userLanguage As String = USER_LANGUAGE
' GridDataLoader mit der RICHTIGEN Tabelle aufrufen
Dim success As Boolean = _gridDataLoader.FillGridData(
_gridControl,
_controlRow,
allColumnDefinitions, ' ← ALLE Spalten, nicht nur SQL!
_parentValidator
)
If success Then
MyControlTableLogger?.Debug("Grid-Daten erfolgreich befüllt")
_gridControl.RefreshDataSource()
Else
MyControlTableLogger?.Warn("Grid-Daten konnten nicht befüllt werden")
End If
Catch ex As Exception
MyControlTableLogger?.Error($"Fehler in FillGridWithData: {ex.Message}", ex)
End Try
End Sub
Private Sub CreateGridViaControlCreator()
If _controlCreator Is Nothing OrElse _controlRow Is Nothing OrElse _dataTable Is Nothing Then
Throw New InvalidOperationException("ControlCreator, ControlRow oder DataTable fehlen.")
End If
Try
MyControlTableLogger?.Debug($"Starte Grid-Erstellung für Control-ID: {_controlID}, Profil-ID: {_profilID}")
' WICHTIG: PanelControl (DevExpress) statt Panel verwenden!
Dim containerPanel As New DevExpress.XtraEditors.PanelControl()
containerPanel.Dock = DockStyle.Fill
containerPanel.Name = "GridContainerPanel"
containerPanel.BorderStyle = DevExpress.XtraEditors.Controls.BorderStyles.NoBorder
Me.Controls.Add(containerPanel)
MyControlTableLogger?.Debug("Container PanelControl erstellt und zum Form hinzugefügt")
' Grid über ControlCreator erstellen - MIT PanelControl als Parent
_gridControl = _controlCreator.CreateExistingGridControl(_controlRow, _dataTable, False, _docCurrency, containerPanel)
If _gridControl Is Nothing Then
MyControlTableLogger?.Warn("CreateExistingGridControl hat Nothing zurückgegeben")
Throw New InvalidOperationException("Grid konnte nicht erstellt werden.")
End If
MyControlTableLogger?.Debug($"GridControl erstellt: {_gridControl.Name}")
MyControlTableLogger?.Debug($"GridControl.Parent nach Erstellung: {_gridControl.Parent?.Name}")
' GridControl sollte bereits vom ControlCreator hinzugefügt worden sein
' Falls nicht, explizit hinzufügen
If _gridControl.Parent Is Nothing Then
containerPanel.Controls.Add(_gridControl)
MyControlTableLogger?.Debug("GridControl manuell zu Container hinzugefügt")
End If
' GridControl konfigurieren
_gridControl.Dock = DockStyle.Fill
_gridControl.Visible = True
_gridControl.BringToFront()
MyControlTableLogger?.Debug($"GridControl Dock-Style gesetzt, Container.Controls.Count: {containerPanel.Controls.Count}")
' GridView-Referenz holen
If _gridControl.MainView IsNot Nothing AndAlso TypeOf _gridControl.MainView Is GridView Then
_gridView = DirectCast(_gridControl.MainView, GridView)
MyControlTableLogger?.Debug($"GridView gefunden: {_gridView.Name}, Columns: {_gridView.Columns.Count}")
' Events registrieren (wie im frmValidator)
AddHandler _gridView.CellValueChanged, AddressOf GridView_CellValueChanged
AddHandler _gridView.KeyDown, AddressOf GridView_KeyDown
AddHandler _gridView.RowDeleting, AddressOf GridView_RowDeleting
MyControlTableLogger?.Debug("GridView Events registriert")
Else
MyControlTableLogger?.Warn($"Kein GridView gefunden. MainView ist: {_gridControl.MainView?.GetType().Name}")
End If
If _dataTable IsNot Nothing Then
AddHandler _dataTable.RowDeleted, AddressOf GridDataSource_RowDeleted
MyControlTableLogger?.Debug($"DataTable Events registriert. Rows: {_dataTable.Rows.Count}")
End If
' Refresh erzwingen
_gridControl.Refresh()
containerPanel.Refresh()
Me.Refresh()
MyControlTableLogger?.Debug("CreateGridViaControlCreator abgeschlossen")
Catch ex As Exception
MyControlTableLogger?.Error($"Fehler in CreateGridViaControlCreator: {ex.Message}", ex)
MyControlTableLogger?.Error($"StackTrace: {ex.StackTrace}")
Throw
End Try
End Sub
Private Sub GridView_CellValueChanged(sender As Object, e As CellValueChangedEventArgs)
' Markiere als geändert
_isDirty = True
MyControlTableLogger?.Debug("Grid-Daten geändert - IsDirty = True")
' Änderungen an Parent-Validator weitergeben, falls notwendig
If _parentValidator IsNot Nothing Then
' Hier können Sie die gleiche Logik wie im frmValidator implementieren
End If
End Sub
Private Sub GridView_KeyDown(sender As Object, e As KeyEventArgs)
If e.KeyCode = Keys.Delete Then
If _gridView IsNot Nothing AndAlso _gridView.SelectedRowsCount > 0 Then
Dim result = XtraMessageBox.Show("Möchten Sie die ausgewählte(n) Zeile(n) wirklich löschen?",
"Löschen bestätigen",
MessageBoxButtons.YesNo,
MessageBoxIcon.Question)
If result = DialogResult.Yes Then
_gridView.DeleteSelectedRows()
End If
End If
End If
End Sub
Private Sub GridView_RowDeleting(sender As Object, e As RowDeletingEventArgs)
' Markiere als geändert beim Löschen
_isDirty = True
MyControlTableLogger?.Debug("Grid-Zeile gelöscht - IsDirty = True")
End Sub
Private Sub GridDataSource_RowDeleted(sender As Object, e As DataRowChangeEventArgs)
' Cleanup nach dem Löschen
CleanupDeletedRows()
End Sub
Private Sub CleanupDeletedRows()
If _dataTable Is Nothing Then Return
Try
Dim rowsToRemove As New List(Of DataRow)
For Each row As DataRow In _dataTable.Rows
If row.RowState = DataRowState.Deleted OrElse row.RowState = DataRowState.Detached Then
rowsToRemove.Add(row)
End If
Next
For Each row In rowsToRemove
Try
If row.RowState <> DataRowState.Detached Then
_dataTable.Rows.Remove(row)
End If
Catch
' Row bereits entfernt
End Try
Next
Catch ex As Exception
' Fehlerbehandlung
End Try
End Sub
Public Function GetGridData() As DataTable
Return _dataTable
End Function
Public Function ValidateGrid() As Boolean
If _gridView Is Nothing Then Return True
Try
_gridView.CloseEditor()
_gridView.UpdateCurrentRow()
Return _gridView.PostEditor()
Catch ex As Exception
Return False
End Try
End Function
Private Sub frmControl_Table_FormClosing(sender As Object, e As FormClosingEventArgs) Handles Me.FormClosing
Try
' Validierung vor dem Schließen
If Not ValidateGrid() Then
Dim result = XtraMessageBox.Show("Es gibt ungespeicherte Änderungen. Trotzdem schließen?",
"Warnung",
MessageBoxButtons.YesNo,
MessageBoxIcon.Warning)
If result = DialogResult.No Then
e.Cancel = True
Return
End If
End If
' Formular-Größe speichern
SaveFormSize()
' Events entfernen
If _gridView IsNot Nothing Then
RemoveHandler _gridView.CellValueChanged, AddressOf GridView_CellValueChanged
RemoveHandler _gridView.KeyDown, AddressOf GridView_KeyDown
RemoveHandler _gridView.RowDeleting, AddressOf GridView_RowDeleting
End If
If _dataTable IsNot Nothing Then
RemoveHandler _dataTable.RowDeleted, AddressOf GridDataSource_RowDeleted
End If
Catch ex As Exception
' Fehlerbehandlung beim Schließen
End Try
End Sub
Private Sub BarButtonItem1_ItemClick(sender As Object, e As DevExpress.XtraBars.ItemClickEventArgs) Handles BarButtonItem1.ItemClick
Try
MyControlTableLogger?.Debug("Daten neu laden angefordert ...")
' Sprachabhängige Texte
Dim title, question, successMessage As String
Select Case USER_LANGUAGE
Case "de-DE"
title = "Daten neu laden"
question = "Möchten Sie die Daten wirklich neu laden?" & vbCrLf & vbCrLf &
"Alle nicht gespeicherten Änderungen gehen verloren!"
successMessage = "Daten wurden erfolgreich neu geladen."
Case "fr-FR"
title = "Recharger les données"
question = "Voulez-vous vraiment recharger les données?" & vbCrLf & vbCrLf &
"Toutes les modifications non enregistrées seront perdues!"
successMessage = "Les données ont été rechargées avec succès."
Case Else ' en-US, en-GB, etc.
title = "Reload Data"
question = "Do you really want to reload the data?" & vbCrLf & vbCrLf &
"All unsaved changes will be lost!"
successMessage = "Data has been successfully reloaded."
End Select
' Benutzer-Bestätigung
Dim result = XtraMessageBox.Show(
question,
title,
MessageBoxButtons.YesNo,
MessageBoxIcon.Question
)
If result = DialogResult.No Then
MyControlTableLogger?.Debug("Reload vom Benutzer abgebrochen")
Return
End If
' GridView zurücksetzen
If _gridView IsNot Nothing Then
_gridView.ClearColumnsFilter()
_gridView.ClearSorting()
_gridView.ClearGrouping()
MyControlTableLogger?.Debug("GridView Filter/Sortierung/Gruppierung gelöscht!")
End If
' Daten neu laden (Spaltenbreiten kommen aus DB!)
FillGridWithData()
' Erfolgs-Meldung
XtraMessageBox.Show(
successMessage,
title,
MessageBoxButtons.OK,
MessageBoxIcon.Information
)
MyControlTableLogger?.Debug("Daten erfolgreich neu geladen")
Catch ex As Exception
MyControlTableLogger?.Error($"Fehler beim Neuladen: {ex.Message}", ex)
' Fehler-Meldung (auch mehrsprachig)
Dim errorTitle As String = If(USER_LANGUAGE = "de-DE", "Fehler", "Error")
Dim errorPrefix As String = If(USER_LANGUAGE = "de-DE", "Fehler beim Neuladen der Daten:", "Error while reloading data:")
XtraMessageBox.Show(
$"{errorPrefix}{vbCrLf}{ex.Message}",
errorTitle,
MessageBoxButtons.OK,
MessageBoxIcon.Error
)
End Try
End Sub
Private Sub BarButtonItem2_ItemClick(sender As Object, e As DevExpress.XtraBars.ItemClickEventArgs) Handles BarButtonItem2.ItemClick
Me.Close()
End Sub
''' <summary>
''' Speichert die aktuelle Formular-Größe und Position in einer XML-Datei
''' </summary>
Private Sub SaveFormSize()
Try
Dim xmlFile As String = GetXML_FormSizeName(_profilID, _controlID)
' XML-Dokument erstellen
Dim xmlDoc As New Xml.XmlDocument()
Dim rootNode As Xml.XmlElement = xmlDoc.CreateElement("FormSize")
xmlDoc.AppendChild(rootNode)
' Größe speichern
Dim widthNode As Xml.XmlElement = xmlDoc.CreateElement("Width")
widthNode.InnerText = Me.Width.ToString()
rootNode.AppendChild(widthNode)
Dim heightNode As Xml.XmlElement = xmlDoc.CreateElement("Height")
heightNode.InnerText = Me.Height.ToString()
rootNode.AppendChild(heightNode)
' Position speichern
Dim leftNode As Xml.XmlElement = xmlDoc.CreateElement("Left")
leftNode.InnerText = Me.Left.ToString()
rootNode.AppendChild(leftNode)
Dim topNode As Xml.XmlElement = xmlDoc.CreateElement("Top")
topNode.InnerText = Me.Top.ToString()
rootNode.AppendChild(topNode)
' WindowState speichern
Dim stateNode As Xml.XmlElement = xmlDoc.CreateElement("WindowState")
stateNode.InnerText = Me.WindowState.ToString()
rootNode.AppendChild(stateNode)
' Verzeichnis erstellen, falls nicht vorhanden
Dim directory As String = System.IO.Path.GetDirectoryName(xmlFile)
If Not String.IsNullOrEmpty(directory) AndAlso Not System.IO.Directory.Exists(directory) Then
System.IO.Directory.CreateDirectory(directory)
End If
' XML speichern
xmlDoc.Save(xmlFile)
MyControlTableLogger?.Debug($"Formular-Größe gespeichert: {xmlFile}")
Catch ex As Exception
MyControlTableLogger?.Error($"Fehler beim Speichern der Formular-Größe: {ex.Message}", ex)
End Try
End Sub
''' <summary>
''' Lädt die gespeicherte Formular-Größe und Position aus der XML-Datei
''' </summary>
Private Sub RestoreFormSize()
Try
Dim xmlFile As String = GetXML_FormSizeName(_profilID, _controlID)
If Not System.IO.File.Exists(xmlFile) Then
MyControlTableLogger?.Debug($"Keine gespeicherte Formular-Größe gefunden: {xmlFile}")
Return
End If
' XML laden
Dim xmlDoc As New Xml.XmlDocument()
xmlDoc.Load(xmlFile)
Dim rootNode As Xml.XmlNode = xmlDoc.SelectSingleNode("FormSize")
If rootNode Is Nothing Then Return
' Größe wiederherstellen
Dim widthNode As Xml.XmlNode = rootNode.SelectSingleNode("Width")
Dim heightNode As Xml.XmlNode = rootNode.SelectSingleNode("Height")
If widthNode IsNot Nothing AndAlso heightNode IsNot Nothing Then
Dim width As Integer = 0
Dim height As Integer = 0
If Integer.TryParse(widthNode.InnerText, width) AndAlso Integer.TryParse(heightNode.InnerText, height) Then
Me.Size = New Size(width, height)
End If
End If
' Position wiederherstellen
Dim leftNode As Xml.XmlNode = rootNode.SelectSingleNode("Left")
Dim topNode As Xml.XmlNode = rootNode.SelectSingleNode("Top")
If leftNode IsNot Nothing AndAlso topNode IsNot Nothing Then
Dim left As Integer = 0
Dim top As Integer = 0
If Integer.TryParse(leftNode.InnerText, left) AndAlso Integer.TryParse(topNode.InnerText, top) Then
Me.Location = New Point(left, top)
End If
End If
' WindowState wiederherstellen
Dim stateNode As Xml.XmlNode = rootNode.SelectSingleNode("WindowState")
If stateNode IsNot Nothing Then
Dim state As FormWindowState
If [Enum].TryParse(Of FormWindowState)(stateNode.InnerText, state) Then
Me.WindowState = state
End If
End If
MyControlTableLogger?.Debug($"Formular-Größe wiederhergestellt: {xmlFile}")
Catch ex As Exception
MyControlTableLogger?.Error($"Fehler beim Wiederherstellen der Formular-Größe: {ex.Message}", ex)
End Try
End Sub
Private Sub BarButtonItem3_ItemClick(sender As Object, e As DevExpress.XtraBars.ItemClickEventArgs) Handles BarButtonItem3.ItemClick
Try
' Sprachabhängige Texte
Dim title, question, successMessage As String
Select Case USER_LANGUAGE
Case "de-DE"
title = "Layout löschen"
question = "Möchten Sie das gespeicherte Layout wirklich löschen?" & vbCrLf & vbCrLf &
"Das Formular wird auf die Standardgröße zurückgesetzt und neu geladen."
successMessage = "Layout wurde erfolgreich gelöscht." & vbCrLf & "Das Formular wird neu geladen..."
Case "fr-FR"
title = "Supprimer la disposition"
question = "Voulez-vous vraiment supprimer la disposition enregistrée?" & vbCrLf & vbCrLf &
"Le formulaire sera réinitialisé à la taille par défaut et rechargé."
successMessage = "La disposition a été supprimée avec succès." & vbCrLf & "Le formulaire va être rechargé..."
Case Else ' en-US, en-GB, etc.
title = "Delete Layout"
question = "Do you really want to delete the saved layout?" & vbCrLf & vbCrLf &
"The form will be reset to the default size and reloaded."
successMessage = "Layout has been successfully deleted." & vbCrLf & "The form will be reloaded..."
End Select
' Benutzer-Bestätigung
Dim result = XtraMessageBox.Show(
question,
title,
MessageBoxButtons.YesNo,
MessageBoxIcon.Question
)
If result = DialogResult.No Then
MyControlTableLogger?.Debug("Layout-Löschung vom Benutzer abgebrochen")
Return
End If
' Layout-Datei löschen
Dim xmlFile As String = GetXML_FormSizeName(_profilID, _controlID)
Dim layoutDeleted As Boolean = False
If System.IO.File.Exists(xmlFile) Then
System.IO.File.Delete(xmlFile)
layoutDeleted = True
MyControlTableLogger?.Debug($"Layout-Datei gelöscht: {xmlFile}")
Else
MyControlTableLogger?.Debug($"Keine Layout-Datei zum Löschen gefunden: {xmlFile}")
End If
' Erfolgs-Meldung
XtraMessageBox.Show(
successMessage,
title,
MessageBoxButtons.OK,
MessageBoxIcon.Information
)
' Formular neu laden
If layoutDeleted Then
MyControlTableLogger?.Debug("Lade Formular nach Layout-Löschung neu...")
' GridView zurücksetzen
If _gridView IsNot Nothing Then
_gridView.ClearColumnsFilter()
_gridView.ClearSorting()
_gridView.ClearGrouping()
MyControlTableLogger?.Debug("GridView Filter/Sortierung/Gruppierung zurückgesetzt")
End If
' Daten neu laden
FillGridWithData()
' Formular auf Standardgröße zurücksetzen
Me.WindowState = FormWindowState.Normal
Me.StartPosition = FormStartPosition.CenterParent
MyControlTableLogger?.Debug("Formular erfolgreich neu geladen")
End If
Catch ex As Exception
MyControlTableLogger?.Error($"Fehler beim Löschen des Layouts: {ex.Message}", ex)
' Fehler-Meldung (mehrsprachig)
Dim errorTitle As String = If(USER_LANGUAGE = "de-DE", "Fehler", If(USER_LANGUAGE = "fr-FR", "Erreur", "Error"))
Dim errorPrefix As String = If(USER_LANGUAGE = "de-DE",
"Fehler beim Löschen des Layouts:",
If(USER_LANGUAGE = "fr-FR",
"Erreur lors de la suppression de la disposition:",
"Error while deleting layout:"))
XtraMessageBox.Show(
$"{errorPrefix}{vbCrLf}{ex.Message}",
errorTitle,
MessageBoxButtons.OK,
MessageBoxIcon.Error
)
End Try
End Sub
End Class