4 Commits

Author SHA1 Message Date
Developer01
d086590eed Fix: Toten Pseudo-Fallback in GridViewWorkflows_MouseDown entfernt
Der InvalidRowHandle-Check in GridViewWorkflows_MouseDown (aus einem
vorherigen Commit) las GridViewWorkflows.FocusedRowHandle in eine
lokale Variable ein, verwendete sie aber nirgends - hi.RowHandle blieb
unverändert ungültig, sodass der Code ohnehin sofort in der nächsten
Prüfung (Not hi.InRow) abbrach. Zusätzlich trug die Debug-Zeile
fälschlich das Präfix "Item_Scope:" statt "MouseDown:" - offensichtlich
ein Kopier-Rest.

Anders als in Item_Scope (siehe vorheriger Commit) ist ein
FocusedRowHandle-Fallback hier bewusst NICHT sinnvoll: e.Location ist
in MouseDown immer die aktuelle Klick-Position (kein Caching-Problem),
und InvalidRowHandle ist der normale, erwartete Fall für legitime
Nicht-Zeilen-Klicks (Spaltenkopf, leerer Bereich, insb.
FilterPanelCloseButton). Ein Fallback auf FocusedRowHandle würde solche
Klicks fälschlich der aktuell fokussierten Zeile zuordnen (z.B. Klick
auf "Filter schließen" würde plötzlich CURRENT_CLICKED_PROFILE_ID
setzen) - neuer Bug statt Fix. Der ursprünglich gemeldete Fehler
(Doppelklick auf Gruppenkopf reagiert nicht) ist bereits durch den
Fallback in Item_Scope abgedeckt, unabhängig vom Ausgang dieses
MouseDown-Aufrufs.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-08-11 15:25:34 +02:00
Developer01
d8eb019d01 Fix: InvalidRowHandle bei Doppelklick auf GroupRow in Item_Scope
Item_Scope() hat den RowHandle über CalcHitInfo(GridCursorLocation)
neu berechnet - basierend auf einer zwischengespeicherten Klick-
Position. Klappt sich eine Gruppe zwischen Klick und Verarbeitung
auf/zu (automatisch durch den DoubleClick-Handler oder manuell durch
den User), verschiebt sich die RowHandle-Nummerierung und die
gecachte Position zeigt ins Leere -> InvalidRowHandle -> Doppelklick
auf Gruppenkopf verpuffte wirkungslos.

- Fallback auf GridViewWorkflows.FocusedRowHandle, wenn der aus
  GridCursorLocation berechnete RowHandle ungültig ist.
- Group-/DataRow-Erkennung erfolgt jetzt einheitlich per
  IsGroupRow/IsDataRow(effectiveRowHandle) statt über die
  potenziell unzuverlässigen hitInfo.InGroupRow/InDataRow-Flags;
  dieser Pfad war zuvor bereits als Bug-Workaround vorhanden und
  wird nun durchgängig genutzt (Schritt-1/Schritt-2-Duplizierung
  entfernt).
- Doppelten "STARTEDROM NORMALISIEREN"-Codeblock (Copy-Paste-Rest)
  bereinigt.

Betrifft sowohl den Doppelklick-Pfad als auch die manuellen Aufrufe
über die Kontextmenü-Buttons (CMROW/CMGROUP), da beide denselben
Codepfad in Item_Scope durchlaufen.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-08-11 15:19:12 +02:00
Developer01
de4f348be5 Verbesserung von Validierungen und State-Management
Die Änderungen umfassen:
- Hinzufügen der Methode `Reset_Current` in `frmMain` zur zentralisierten Rücksetzung von Zuständen.
- Erweiterung von `Item_Scope` mit Validierungen für ungültige Klicks und Fallback-Logik bei DevExpress-Bugs.
- Verbesserte Fehlerbehandlung und Validierungen im `DoubleClick`- und `MouseDown`-Handler.
- Einführung der Methode `ParseColorString` zur sicheren Verarbeitung von Farbwerten.
- Optimierung von `TreeList_Cockpit_DoubleClick` mit Debugging-Logs und State-Reset.
- Hinzufügen von State-Reset-Logik in `frmValidator` (`previousLUSelectedValues`, `hadPreviousLUSelection`).
- Verbesserte Sicherung und Wiederherstellung von Lookup-Werten in `FillIndexValues`.
- SQL-Optimierung: Löschen von Einträgen in `TBTF_PROFILE_FILES_WORK`.
- Erweiterte Debugging-Informationen und Fehlerbehandlung in mehreren Methoden.
2026-08-11 14:53:26 +02:00
Developer01
4609ea8ad7 Verbesserung: Caching und Thread-Sicherheit hinzugefügt
Neue private Felder `_separateGridDataCache` und
`_separateGridControlCache` für das Caching von Daten und
Steuerelementen eingeführt, um die Performance zu verbessern.

Die neuen Caches werden beim Laden eines neuen Dokuments
explizit geleert, um Konsistenz sicherzustellen.

Ein zusätzlicher Aufruf von `Check_UpdateIndexe(False)` wurde
hinzugefügt, um erweiterte Funktionalität zu ermöglichen.

Allgemeine Verbesserungen der Thread-Sicherheit durch die
Verwendung von Locks (`_overlayLock`) implementiert.
2026-08-10 16:16:14 +02:00
2 changed files with 206 additions and 70 deletions

View File

@@ -2492,6 +2492,14 @@ Public Class frmMain
End If
End Try
End Sub
Private Sub Reset_Current()
CURRENT_JUMP_DOC_GUID = 0
CURRENT_DOC_GUID = 0
CURRENT_DOC_ID = 0
CURRENT_ProfilGUID = 0
CURRENT_CLICKED_PROFILE_ID = 0
DT_CURR_WF_ITEMS.Clear()
End Sub
Private Async Function Item_Scope(startedFrom As String) As Task
' ========== FRÜHE VALIDIERUNGEN (VOR UI-ÄNDERUNGEN) ==========
If Application.OpenForms().OfType(Of frmValidator).Any Then
@@ -2514,38 +2522,80 @@ Public Class frmMain
Try
LOGGER.Info("Starting Profile Loading")
Reset_Current()
' ========== UI-VORBEREITUNG ==========
Me.UseWaitCursor = True
useWaitCursorApplied = True
bsiMessage.Caption = "Processing selection..."
messageApplied = True
' ========== HITINFO NUR EINMAL BERECHNEN ==========
Dim hitInfo As GridHitInfo = GridViewWorkflows.CalcHitInfo(GridCursorLocation)
' ========== STARTEDROM NORMALISIEREN ==========
If startedFrom = "DOUBLECLICK" Then
startedFrom = If(hitInfo.InGroupRow, "CMGROUP", "CMROW")
LOGGER.Debug($"User clicked {If(hitInfo.InGroupRow, "group", "normal")} row.")
' ===== EFFEKTIVEN ROWHANDLE ERMITTELN (MIT FALLBACK) =====
' hitInfo basiert auf der zwischengespeicherten Klick-Position (GridCursorLocation).
' Diese kann zwischen Klick und Verarbeitung ungültig werden - z.B. wenn eine Gruppe
' zwischenzeitlich auf-/zugeklappt wurde (automatisch durch den DoubleClick-Handler
' oder manuell durch den User) und sich dadurch die RowHandle-Nummerierung verschoben hat.
' In diesem Fall auf FocusedRowHandle ausweichen, das vom Grid selbst nachgeführt wird
' und i.d.R. weiterhin die angeklickte Zeile referenziert.
Dim effectiveRowHandle As Integer = hitInfo.RowHandle
If effectiveRowHandle = DevExpress.XtraGrid.GridControl.InvalidRowHandle Then
Dim focusedRowHandle = GridViewWorkflows.FocusedRowHandle
If focusedRowHandle <> DevExpress.XtraGrid.GridControl.InvalidRowHandle Then
LOGGER.Debug($"Item_Scope: CalcHitInfo(GridCursorLocation) invalid - falling back to FocusedRowHandle [{focusedRowHandle}]")
effectiveRowHandle = focusedRowHandle
Else
LOGGER.Warn($"⚠️ Item_Scope: InvalidRowHandle detected (click on empty grid area?) - exiting")
Exit Function
End If
End If
' ========== PROFIL-ID ERMITTELN (OPTIMIERT) ==========
' ===== GROUP-/DATAROW DIREKT AM ROWHANDLE PRÜFEN =====
' Robuster als hitInfo.InGroupRow/InDataRow: funktioniert unverändert für den
' FocusedRowHandle-Fallback und umgeht einen bekannten DevExpress-Bug, bei dem
' diese hitInfo-Flags trotz gültigem RowHandle falsch gesetzt sein können.
Dim isGroupRow As Boolean = GridViewWorkflows.IsGroupRow(effectiveRowHandle)
Dim isDataRow As Boolean = GridViewWorkflows.IsDataRow(effectiveRowHandle)
If Not isGroupRow AndAlso Not isDataRow Then
LOGGER.Warn($"⚠️ Item_Scope: RowHandle [{effectiveRowHandle}] ist weder Group- noch DataRow - exiting")
Exit Function
End If
' ===== STARTEDROM NORMALISIEREN =====
If startedFrom = "DOUBLECLICK" Then
startedFrom = If(isGroupRow, "CMGROUP", "CMROW")
LOGGER.Debug($"User clicked {If(isGroupRow, "group", "normal")} row.")
End If
' ========== PROFIL-ID ERMITTELN ==========
Dim oHitProfilID As Object = Nothing
If hitInfo.InGroupRow Then
If isGroupRow Then
' ✅ Gruppenkopf: Profil-ID aus erster Datenzeile der Gruppe
oHitProfilID = GridViewWorkflows.GetRowCellValue(
GridViewWorkflows.GetDataRowHandleByGroupRowHandle(hitInfo.RowHandle),
GridViewWorkflows.GetDataRowHandleByGroupRowHandle(effectiveRowHandle),
GridViewWorkflows.Columns("PROFILE_ID"))
ElseIf hitInfo.InDataRow Then
LOGGER.Debug("Clicked on Group Row")
ElseIf isDataRow Then
' ✅ Normale Datenzeile: Profil-ID direkt aus dieser Zeile
oHitProfilID = GridViewWorkflows.GetRowCellValue(
GridViewWorkflows.GetDataRowHandleByGroupRowHandle(
GridViewWorkflows.GetParentRowHandle(hitInfo.RowHandle)),
effectiveRowHandle,
GridViewWorkflows.Columns("PROFILE_ID"))
LOGGER.Debug("Clicked on Data Row")
End If
LOGGER.Debug("Clicked ProfileId: [{0}], Started From: [{1}]", oHitProfilID, startedFrom)
' ========== PROFIL-ID VALIDIERUNG UND UPDATE ==========
' ========== PROFIL-ID VALIDIERUNG ==========
If oHitProfilID Is Nothing OrElse Not IsNumeric(oHitProfilID) OrElse CInt(oHitProfilID) = 0 Then
LOGGER.Warn("⚠️ Item_Scope: Could not determine valid PROFILE_ID from clicked row!")
FormHelper.ShowInfoMessage("Konnte keine gültige Profil-ID ermitteln!", omsgTitleWarning)
Exit Function
End If
' ========== PROFIL-ID UPDATE ==========
If oHitProfilID IsNot Nothing AndAlso IsNumeric(oHitProfilID) AndAlso CInt(oHitProfilID) > 0 Then
If oHitProfilID <> CURRENT_CLICKED_PROFILE_ID Then
LOGGER.Debug($"Item_Scope: oHitProfilID {oHitProfilID} <> CURRENT_CLICKED_PROFILE_ID {CURRENT_CLICKED_PROFILE_ID}")
@@ -2559,15 +2609,15 @@ Public Class frmMain
Dim oGroupRowHandle As Integer
' KRITISCH: Den RICHTIGEN Gruppen-Handle ermitteln
If GridViewWorkflows.IsGroupRow(hitInfo.RowHandle) Then
If isGroupRow Then
' User hat direkt auf die Gruppen-Zeile geklickt
oGroupRowHandle = hitInfo.RowHandle
oGroupRowHandle = effectiveRowHandle
LOGGER.Debug($"User clicked directly on group row, handle: {oGroupRowHandle}")
Else
' User hat auf eine Daten-Zeile INNERHALB einer Gruppe geklickt
' → Parent-Gruppe ermitteln
oGroupRowHandle = GridViewWorkflows.GetParentRowHandle(hitInfo.RowHandle)
LOGGER.Debug($"User clicked on data row {hitInfo.RowHandle}, parent group handle: {oGroupRowHandle}")
oGroupRowHandle = GridViewWorkflows.GetParentRowHandle(effectiveRowHandle)
LOGGER.Debug($"User clicked on data row {effectiveRowHandle}, parent group handle: {oGroupRowHandle}")
If Not GridViewWorkflows.IsGroupRow(oGroupRowHandle) Then
LOGGER.Warn($"⚠️ Parent handle {oGroupRowHandle} is not a group row!")
@@ -2696,12 +2746,12 @@ Public Class frmMain
' ========== PROFIL-TITEL ERMITTELN ==========
Dim PROFIL_TITLE As String = String.Empty
If hitInfo.InGroupRow Then
If isGroupRow Then
GridViewItem_Clicked = "GROUP"
startedFrom = "CMGROUP"
LOGGER.Debug($"Item_Scope: InGroupRow")
Dim groupRowText = GridViewWorkflows.GetGroupRowDisplayText(hitInfo.RowHandle)
Dim groupRowText = GridViewWorkflows.GetGroupRowDisplayText(effectiveRowHandle)
LOGGER.Debug($"Item_Scope: groupRowText {groupRowText}")
If GRID_LOAD_TYPE = "OVERVIEW" Then
@@ -2710,14 +2760,14 @@ Public Class frmMain
PROFIL_TITLE = If(splitIndex >= 0, groupRowText.Substring(0, splitIndex).Trim(), groupRowText)
End If
ElseIf hitInfo.InDataRow Then
ElseIf isDataRow Then
GridViewItem_Clicked = "ROW"
LOGGER.Debug($"Item_Scope: InDataRow")
If GRID_LOAD_TYPE = "OVERVIEW" Then
LOGGER.Debug($"Item_Scope: GRID_LOAD_TYPE = OVERVIEW")
Dim groupRowText = GridViewWorkflows.GetGroupRowDisplayText(
GridViewWorkflows.GetParentRowHandle(hitInfo.RowHandle))
GridViewWorkflows.GetParentRowHandle(effectiveRowHandle))
LOGGER.Debug($"Item_Scope: OVERVIEWgroupRowText {groupRowText}")
groupRowText = groupRowText.Replace("Profile (Fixed): ", "").Trim()
@@ -2746,18 +2796,16 @@ Public Class frmMain
If Not IsNothing(CURRENT_CLICKED_PROFILE_ID) AndAlso IsNumeric(CURRENT_CLICKED_PROFILE_ID) Then
LOGGER.Debug($"Item_Scope: Valid PROFIL_ID")
If hitInfo.InGroupRow OrElse (startedFrom = "CMGROUP" AndAlso hitInfo.InDataRow) Then
If isGroupRow OrElse (startedFrom = "CMGROUP" AndAlso isDataRow) Then
' GRUPPE: Workflow ohne spezifisches Dokument
CURRENT_JUMP_DOC_GUID = 0
CURRENT_DOC_GUID = 0
CURRENT_DOC_ID = 0
Reset_Current()
CURRENT_ProfilGUID = CURRENT_CLICKED_PROFILE_ID
LOGGER.Debug($"Item_Scope: hitInfo.InGroupRow...CURRENT_CLICKED_PROFILE_ID [{CURRENT_CLICKED_PROFILE_ID}]")
LOGGER.Debug($"Item_Scope: isGroupRow...CURRENT_CLICKED_PROFILE_ID [{CURRENT_CLICKED_PROFILE_ID}]")
Load_Profil_from_Grid(CURRENT_CLICKED_PROFILE_ID)
ElseIf hitInfo.InDataRow Then
ElseIf isDataRow Then
' EINZELNE ZEILE: Mit spezifischem Dokument
LOGGER.Debug($"Item_Scope: hitInfo.InDataRow...")
LOGGER.Debug($"Item_Scope: isDataRow...")
' ========== DOKUMENT-DATEN ABRUFEN ==========
Dim oFocusedDocGUID = GridViewWorkflows.GetFocusedRowCellValue(GridViewWorkflows.Columns("GUID"))
@@ -2765,7 +2813,7 @@ Public Class frmMain
' Validierungen
If oFocusedDocID Is Nothing Then
LOGGER.Warn("⚠️ In hitInfo.InDataRow: DocID is nothing!!!")
LOGGER.Warn("⚠️ In isDataRow: DocID is nothing!!!")
bsiMessage.Caption = "Error getting DocID!"
bsiMessage.ItemAppearance.Normal.BackColor = Color.Red
bsiMessage.ItemAppearance.Normal.ForeColor = Color.Black
@@ -2773,7 +2821,7 @@ Public Class frmMain
End If
If oFocusedDocGUID Is Nothing Then
LOGGER.Warn("⚠️ In hitInfo.InDataRow: oFocusedDocGUID is nothing!!!")
LOGGER.Warn("⚠️ In isDataRow: oFocusedDocGUID is nothing!!!")
bsiMessage.Caption = "Error getting DocGUID!"
bsiMessage.ItemAppearance.Normal.BackColor = Color.Red
bsiMessage.ItemAppearance.Normal.ForeColor = Color.Black
@@ -3315,9 +3363,47 @@ Public Class frmMain
End Function
Private Async Sub GridViewWorkflows_DoubleClick(sender As Object, e As EventArgs) Handles GridViewWorkflows.DoubleClick
Me.Cursor = Cursors.WaitCursor
Await Item_Scope("DOUBLECLICK")
Me.Cursor = Cursors.Default
Try
' ===== KRITISCH: HitInfo MIT AKTUELLEM Mauszeiger-Position berechnen =====
Dim oCurrentMousePosition As System.Drawing.Point = GridControlWorkflows.PointToClient(Cursor.Position)
Dim hitInfo As GridHitInfo = GridViewWorkflows.CalcHitInfo(oCurrentMousePosition)
' ===== FRÜHE VALIDIERUNG =====
If hitInfo.RowHandle = DevExpress.XtraGrid.GridControl.InvalidRowHandle Then
Dim focused = GridViewWorkflows.FocusedRowHandle
If focused <> DevExpress.XtraGrid.GridControl.InvalidRowHandle Then
LOGGER.Debug($"Item_Scope: hitInfo invalid, falling back to FocusedRowHandle [{focused}]")
' hitInfo/rowHandle entsprechend neu aufbauen
CURRENT_CLICKED_PROFILE_ID = GridViewWorkflows.GetRowCellValue(GridViewWorkflows.GetDataRowHandleByGroupRowHandle(focused), GridViewWorkflows.Columns("PROFILE_ID"))
LOGGER.Debug($"Item_Scope: Fallback PROFILE_ID = [{CURRENT_CLICKED_PROFILE_ID}]")
Else
LOGGER.Warn("⚠️ Item_Scope: InvalidRowHandle detected...")
Exit Sub
End If
End If
If Not hitInfo.InRow Then
LOGGER.Warn("⚠️ DoubleClick: Not in row - ignoring")
Exit Sub
End If
' ===== AKTUALISIERTE GridCursorLocation SETZEN =====
GridCursorLocation = oCurrentMousePosition
LOGGER.Debug($"DoubleClick: RowHandle=[{hitInfo.RowHandle}], InGroupRow=[{hitInfo.InGroupRow}], InDataRow=[{hitInfo.InDataRow}]")
Me.Cursor = Cursors.WaitCursor
Try
Await Item_Scope("DOUBLECLICK")
Finally
Me.Cursor = Cursors.Default
End Try
Catch ex As Exception
LOGGER.Error(ex)
Me.Cursor = Cursors.Default
End Try
End Sub
'Private Sub GridViewWorkflows_CustomDrawGroupRow(sender As Object, e As Views.Base.RowObjectCustomDrawEventArgs) Handles GridViewWorkflows.CustomDrawGroupRow
@@ -3372,7 +3458,6 @@ Public Class frmMain
Private Sub GridViewWorkflows_CustomDrawGroupRow(sender As Object, e As Views.Base.RowObjectCustomDrawEventArgs) Handles GridViewWorkflows.CustomDrawGroupRow
Try
If FormOpenClose = True And GridIsLoaded = False Then
Exit Sub
End If
@@ -3387,11 +3472,27 @@ Public Class frmMain
If oInfo.Column.FieldName = "GROUP_TEXT" Then
oInfo.GroupText = oInfo.GroupValueText
' ===== PRÜFUNG AUF KINDERZEILEN HINZUFÜGEN =====
Dim oChildCount As Integer = oView.GetChildRowCount(oInfo.RowHandle)
' Wenn keine Kinder vorhanden sind, Standard-Farben verwenden
If oChildCount = 0 Then
LOGGER.Debug($"CustomDrawGroupRow: Group [{oInfo.GroupValueText}] has no children - using default colors")
oInfo.Appearance.BackColor = Color.LightGray
oInfo.Appearance.ForeColor = Color.Black
Exit Sub
End If
' ===== NUR BEI VORHANDENEN KINDERN FARBE AUSLESEN =====
Dim oColorString As String = "LightGray"
Dim oFontColorString As String = "Black"
Dim oChildRowHandle As Integer = oView.GetChildRowHandle(oInfo.RowHandle, 0)
oColorString = oView.GetRowCellValue(oChildRowHandle, "GROUP_COLOR")
' GetRowCellValue kann Nothing zurückgeben, daher absichern
Dim oCellValue As Object = oView.GetRowCellValue(oChildRowHandle, "GROUP_COLOR")
If oCellValue IsNot Nothing AndAlso Not IsDBNull(oCellValue) Then
oColorString = oCellValue.ToString()
End If
Dim oColor As Color = ParseColorString(oColorString, Color.LightGray, "Background Color")
Dim oFontColor As Color = ParseColorString(oFontColorString, Color.Black, "Font Color")
@@ -3405,6 +3506,11 @@ Public Class frmMain
End Sub
Private Function ParseColorString(ColorString As String, DefaultColor As Color, ColorDescription As String) As Color
' ===== NULL-CHECK HINZUFÜGEN =====
If String.IsNullOrWhiteSpace(ColorString) Then
LOGGER.Debug($"ParseColorString: ColorString is null/empty for {ColorDescription} - using default color")
Return DefaultColor
End If
Dim oResultColor As Color
If ColorString.Contains(";") Or ColorString.Contains(".") Then
@@ -3439,6 +3545,22 @@ Public Class frmMain
Dim view As GridView = sender
Dim hi As GridHitInfo = view.CalcHitInfo(e.Location)
Dim groupRowButtonClicked = (hi.HitTest = GridHitTest.RowGroupButton)
' ===== UNGÜLTIGE CLICKS ABFANGEN =====
' Anders als in Item_Scope ist hier KEIN FocusedRowHandle-Fallback sinnvoll:
' e.Location ist immer aktuell (kein Caching-Problem), und InvalidRowHandle ist
' hier der normale Fall für legitime Nicht-Zeilen-Klicks (Spaltenkopf, leerer
' Bereich, FilterPanelCloseButton). Ein Fallback würde solche Klicks fälschlich
' der aktuell fokussierten Zeile zuordnen.
If hi.RowHandle = DevExpress.XtraGrid.GridControl.InvalidRowHandle Then
LOGGER.Debug("MouseDown: InvalidRowHandle - ignoring click")
Exit Sub
End If
If Not hi.InRow Then
LOGGER.Debug($"MouseDown: Click not in row (HitTest:[{hi.HitTest}]) - ignoring")
Exit Sub
End If
GridCursorLocation = e.Location
'If e.Button = MouseButtons.Left Then
@@ -3449,18 +3571,21 @@ Public Class frmMain
GridViewItem_Clicked = "GROUP"
If Not Application.OpenForms().OfType(Of frmValidator).Any Then
CURRENT_CLICKED_PROFILE_ID = GridViewWorkflows.GetRowCellValue(GridViewWorkflows.GetDataRowHandleByGroupRowHandle(hi.RowHandle), GridViewWorkflows.Columns("PROFILE_ID"))
LOGGER.Debug($"MouseDown: PROFILE_ID for GroupRow [{hi.RowHandle}] is [{CURRENT_CLICKED_PROFILE_ID}]")
End If
ElseIf hi.InDataRow Then
GridViewItem_Clicked = "ROW"
If Not Application.OpenForms().OfType(Of frmValidator).Any Then
CURRENT_CLICKED_PROFILE_ID = GridViewWorkflows.GetRowCellValue(GridViewWorkflows.GetDataRowHandleByGroupRowHandle(hi.RowHandle), GridViewWorkflows.Columns("PROFILE_ID"))
LOGGER.Debug($"MouseDown: PROFILE_ID for DataRow [{hi.RowHandle}] is [{CURRENT_CLICKED_PROFILE_ID}]")
End If
Else
GridViewItem_Clicked = Nothing
If hi.HitTest = GridHitTest.FilterPanelCloseButton Then
Ev_Filter_Panel_Closed = True
LOGGER.Debug("MouseDown: FilterPanelCloseButton clicked - Ev_Filter_Panel_Closed set to True")
Grid_Reset_Filter()
Ev_Filter_Panel_Closed = False
End If
@@ -3471,6 +3596,7 @@ Public Class frmMain
For Each orow As DataRow In CURRENT_DT_PROFILES.Rows
If orow.Item("GUID") = CURRENT_CLICKED_PROFILE_ID Then
If Not Application.OpenForms().OfType(Of frmValidator).Any Then
LOGGER.Debug($"MouseDown: PROFILE_TITLE for PROFILE_ID [{CURRENT_CLICKED_PROFILE_ID}] is [{orow.Item("TITLE")}]")
CURRENT_CLICKED_PROFILE_TITLE = orow.Item("TITLE")
End If
@@ -4972,10 +5098,10 @@ FROM VWPM_PROFILE_ACTIVE T WHERE T.GUID IN (SELECT PROFILE_ID FROM [dbo].[FNPM_G
Dim oProfileId As Integer = CInt(oFkProfileId)
LOGGER.Debug($"TreeList_Cockpit_DoubleClick: Opening validator for profile ID [{oProfileId}]")
Reset_Current()
' ===== PROFIL-DATEN INS GRID LADEN (FALLS NOCH NICHT GELADEN) =====
' Wenn das Grid aktuell leer ist oder ein anderes Profil zeigt, müssen wir erst laden
If GRID_LOAD_TYPE <> $"PROFILE#{oProfileId}" OrElse DT_CURR_WF_ITEMS Is Nothing OrElse DT_CURR_WF_ITEMS.Rows.Count = 0 Then
If DT_CURR_WF_ITEMS Is Nothing OrElse DT_CURR_WF_ITEMS.Rows.Count = 0 Then
LOGGER.Debug($"TreeList_Cockpit_DoubleClick: Grid does not show profile [{oProfileId}] - loading it first")
CURRENT_CLICKED_PROFILE_ID = oProfileId
@@ -5001,6 +5127,8 @@ FROM VWPM_PROFILE_ACTIVE T WHERE T.GUID IN (SELECT PROFILE_ID FROM [dbo].[FNPM_G
FormHelper.ShowInfoMessage(omsg, omsgTitleAttention)
Exit Sub
End If
Else
LOGGER.Debug($"TreeList_Cockpit_DoubleClick: Grid already shows profile [{CURRENT_CLICKED_PROFILE_ID}] with [{DT_CURR_WF_ITEMS.Rows.Count}] items")
End If
' ===== DOCIDS AUS DT_CURR_WF_ITEMS SAMMELN =====

View File

@@ -142,7 +142,12 @@ Public Class frmValidator
Private _overlayLock As New Object() ' ← NEU: Thread-Safe Lock
Private _documentPathHandler As DocumentPathHandler
Private _isLoadingAdditionalSearches As Boolean = False
Private _separateGridDataCache As New Dictionary(Of String, DataTable)
' Bei den anderen Private-Deklarationen:
Private _separateGridControlCache As New Dictionary(Of String, GridControl)
' ========== BUGFIX START: Alte SelectedValues SICHERN bevor DataSource überschrieben wird ==========
Private previousLUSelectedValues As List(Of String) = Nothing
Private hadPreviousLUSelection As Boolean = False
Private Class Translation_Strings
Inherits My.Resources.frmValidator_Strings
@@ -812,9 +817,9 @@ Public Class frmValidator
End If
Try
Dim oSQL As String
oSQL = $"DELETE FROM TBPM_DOCWALKOVER WHERE UserID = {USER_ID};" & vbCrLf &
$"DELETE FROM TBPM_VALIDATION_PROFILE_GROUP_USER WHERE UserID = {USER_ID};"
Dim oSQL = $"DELETE FROM TBPM_DOCWALKOVER WHERE UserID = {USER_ID};" & vbCrLf &
$"DELETE FROM TBPM_VALIDATION_PROFILE_GROUP_USER WHERE UserID = {USER_ID};" & vbCrLf &
$"DELETE FROM TBTF_PROFILE_FILES_WORK WHERE Action_UserID = {USER_ID};"
DatabaseFallback.ExecuteNonQueryECM(oSQL)
Catch ex As Exception
MyValidationLogger.Error(ex)
@@ -899,6 +904,9 @@ Public Class frmValidator
If Not IsNothing(DT_AdditionalSearches_Resultset_Docs) Then
DT_AdditionalSearches_Resultset_Docs.Clear()
End If
' Lookup-State zurücksetzen
previousLUSelectedValues = Nothing
hadPreviousLUSelection = False
End Sub
Private Sub CleanupTempFolder()
@@ -1784,7 +1792,9 @@ Public Class frmValidator
End If
End Select
Next
' Lookup-State zurücksetzen
previousLUSelectedValues = Nothing
hadPreviousLUSelection = False
Focus_FirstControl()
End Sub
@@ -3795,7 +3805,7 @@ Public Class frmValidator
oBIT = 1
End If
Dim oSQL = $"EXEC PRPM_GET_NEXT_DOC_INFO {CURRENT_ProfilGUID},{CURRENT_DOC_ID},{USER_ID}"
MyValidationLogger.Debug($"Get_Next_GUID: SQL [{oSQL}]...")
Dim oDT As DataTable = DatabaseFallback.GetDatatableECM(oSQL)
CURRENT_DOC_ID = 0
CURRENT_DOC_GUID = 0
@@ -3804,7 +3814,7 @@ Public Class frmValidator
oNewGUID = oDT.Rows(0).Item(0)
MyValidationLogger.Info($"Get_Next_GUID: oNewGUID [{oNewGUID}]...")
Catch ex As Exception
MyValidationLogger.Warn($"⚠️ >> Attention: in GetNextGUID - Could not get the next GUID - SQL [{oSQL}]")
MyValidationLogger.Warn($"⚠️ Attention: in GetNextGUID - Could not get the next GUID - SQL [{oSQL}]")
MyValidationLogger.Warn($"⚠️ ERRORMESSAGE [{ex.Message}]")
End Try
@@ -4049,7 +4059,9 @@ Public Class frmValidator
MyValidationLogger.Info($"LOG_HOTSPOTS - CURRENT_DOC_GUID: {CURRENT_DOC_GUID}")
' ========== ENDE DIAGNOSE ==========
End If
' State-Variablen zurücksetzen beim Laden eines neuen Dokuments
previousLUSelectedValues = Nothing
hadPreviousLUSelection = False
Dim oMilliseconts As Double
clsPatterns.ClearControlCache() ' Cache-Invalidierung
Dim perfStart As DateTime = DateTime.MinValue
@@ -4062,6 +4074,8 @@ Public Class frmValidator
_CachedSqlDataCache.Clear()
_CachedSqlScalarCache.Clear()
_separateGridDataCache.Clear()
_separateGridControlCache.Clear()
_CachedSqlControlsByGuid = Nothing
CURRENT_WMFILE = Nothing
activate_controls(False)
@@ -5643,16 +5657,14 @@ Public Class frmValidator
Dim oLookup As LookupControl3 = oControl
Dim oLookupMeta As ClassControlCreator.ControlMetadata = DirectCast(oLookup.Tag, ClassControlCreator.ControlMetadata)
' ========== BUGFIX START: Alte SelectedValues SICHERN bevor DataSource überschrieben wird ==========
Dim previousSelectedValues As List(Of String) = Nothing
Dim hadPreviousSelection As Boolean = False
If oLookup.Properties.SelectedValues IsNot Nothing AndAlso oLookup.Properties.SelectedValues.Count > 0 Then
previousSelectedValues = New List(Of String)(oLookup.Properties.SelectedValues)
hadPreviousSelection = True
MyValidationLogger.Debug($"[FillIndexValues BUGFIX] Lookup [{oLookupMeta.Name}]: Alte SelectedValues gesichert = [{String.Join(",", previousSelectedValues)}]")
' Nur sichern wenn NICHT bereits von einem vorherigen Dokument vorhanden
If Not hadPreviousLUSelection Then
If oLookup.Properties.SelectedValues IsNot Nothing AndAlso oLookup.Properties.SelectedValues.Count > 0 Then
previousLUSelectedValues = New List(Of String)(oLookup.Properties.SelectedValues)
hadPreviousLUSelection = True
MyValidationLogger.Debug($"[FillIndexValues BUGFIX] Lookup [{oLookupMeta.Name}]: Alte SelectedValues gesichert = [{String.Join(",", previousLUSelectedValues)}]")
End If
End If
' ========== BUGFIX END: Sicherung ==========
oValueFromSource = GetVariableValuefromSource(oSourceIndexName, oIDBTyp, oIDBOverride)
@@ -5685,20 +5697,20 @@ Public Class frmValidator
End If
Else
' ========== BUGFIX START: Wenn KEIN neuer Wert, alte Werte behalten ==========
If hadPreviousSelection AndAlso previousSelectedValues IsNot Nothing AndAlso previousSelectedValues.Count > 0 Then
If hadPreviousLUSelection AndAlso previousLUSelectedValues IsNot Nothing AndAlso previousLUSelectedValues.Count > 0 Then
MyValidationLogger.Debug($"[FillIndexValues BUGFIX] Lookup [{oLookupMeta.Name}]: Kein neuer Wert von Quelle → alte Werte BEHALTEN")
oNewValues = previousSelectedValues
oNewValues = previousLUSelectedValues
ElseIf oDefaultValue <> String.Empty Then
MyValidationLogger.Debug($"[FillIndexValues BUGFIX] Lookup [{oLookupMeta.Name}]: Keine alten Werte, verwende DefaultValue = [{oDefaultValue}]")
MyValidationLogger.Debug($"[FillIndexValues BUGFIX] Lookup [{oLookupMeta.Name}]: Verwende DefaultValue = [{oDefaultValue}]")
oNewValues = oDefaultValue.Split(",").ToList()
Else
MyValidationLogger.Debug($"[FillIndexValues BUGFIX] Lookup [{oLookupMeta.Name}]: KEINE Werte (oValueFromSource=Nothing, oDefaultValue leer, keine vorherigen Werte)")
MyValidationLogger.Debug($"[FillIndexValues BUGFIX] Lookup [{oLookupMeta.Name}]: KEINE Werte!")
End If
' ========== BUGFIX END: Wert-Beibehaltung ==========
End If
' ========== BUGFIX END: Wert-Beibehaltung ==========
End If
' ========== KRITISCH: DataSource-Backup erstellen BEVOR SelectedValues gelöscht wird ==========
Dim savedDataSource = oLookup.Properties.DataSource
' ========== KRITISCH: DataSource-Backup erstellen BEVOR SelectedValues gelöscht wird ==========
Dim savedDataSource = oLookup.Properties.DataSource
MyValidationLogger.Debug($"[FillIndexValues BUGFIX] Lookup [{oLookupMeta.Name}]: DataSource-Backup erstellt")
' ========== KRITISCH: DataSource ZUERST wiederherstellen, DANN SelectedValues leeren ==========
@@ -8502,8 +8514,9 @@ Public Class frmValidator
Cursor = Cursors.WaitCursor
Dim perfStart As DateTime = If(LOG_HOTSPOTS, DateTime.Now, Nothing)
Dim perfLastCheck As DateTime = perfStart
' ========== WICHTIG: State-Variablen zurücksetzen vor neuem Dokument ==========
previousLUSelectedValues = Nothing
hadPreviousLUSelection = False
If LOG_HOTSPOTS Then
' ========== DIAGNOSE START ==========
@@ -8525,12 +8538,7 @@ Public Class frmValidator
' ========== ENDE DIAGNOSE ==========
End If
Reset_CurrentReferences()
If LOG_HOTSPOTS Then
MyValidationLogger.Info($"[PERF] Nach Reset_CurrentReferences: {(DateTime.Now - perfLastCheck).TotalMilliseconds}ms")
perfLastCheck = DateTime.Now
@@ -8594,7 +8602,7 @@ Public Class frmValidator
ShowOverlaySafe() ' ✅ Overlay hier öffnen
Try
' ========== FIX 2: Nur EINEN Check-Aufruf ==========
If Check_UpdateIndexe() = True Then
If Check_UpdateIndexe(False) = True Then
SetStatusLabel("Data saved", "LimeGreen")
MyValidationLogger.Info("Workflowdata saved manually!")