2.8.4 Beta IDB replace Hochkomma bei Delete, Währungskonvertierung

This commit is contained in:
Developer01
2026-03-11 12:08:46 +01:00
parent 41e46f9dbb
commit 7629d54fe1
8 changed files with 444 additions and 222 deletions

View File

@@ -69,6 +69,8 @@ Public Class ClassControlCreator
Public Property GridTables As New Dictionary(Of Integer, Dictionary(Of String, RepositoryItem)) Public Property GridTables As New Dictionary(Of Integer, Dictionary(Of String, RepositoryItem))
Public Property GridColumns As New Dictionary(Of Integer, DataTable) Public Property GridColumns As New Dictionary(Of Integer, DataTable)
''' <summary> ''' <summary>
''' Standard Eigenschaften für alle Controls ''' Standard Eigenschaften für alle Controls
''' </summary> ''' </summary>
@@ -533,12 +535,11 @@ Public Class ClassControlCreator
End Function End Function
Public Function CreateExistingGridControl(row As DataRow, DT_MY_COLUMNS As DataTable, designMode As Boolean, pcurrencySymbol As String) As GridControl Public Function CreateExistingGridControl(row As DataRow, DT_MY_COLUMNS As DataTable, designMode As Boolean, pcurrencySymbol As String) As GridControl
Dim oGridControlCreator = New ControlCreator.GridControl(LogConfig, GridTables) Dim oGridControlCreator = New ControlCreator.GridControl(LogConfig, GridTables, pcurrencySymbol)
Dim oControl As GridControl = CreateBaseControl(New GridControl(), row, designMode) Dim oControl As GridControl = CreateBaseControl(New GridControl(), row, designMode)
Dim oControlId = DirectCast(oControl.Tag, ControlMetadata).Guid Dim oControlId = DirectCast(oControl.Tag, ControlMetadata).Guid
Dim oView As GridView Dim oView As GridView
Dim oControlName = oControl.Name Dim oControlName = oControl.Name
oControl.ForceInitialize() oControl.ForceInitialize()
oView = oControl.MainView oView = oControl.MainView
@@ -635,9 +636,13 @@ Public Class ClassControlCreator
End Try End Try
End If End If
oGridControlCreator.ConfigureViewColumns(DT_MY_COLUMNS, oView, oControl, pcurrencySymbol) ' *** KORRIGIERT: ConfigureViewColumns OHNE currencySymbol-Parameter ***
oGridControlCreator.ConfigureViewColumns(DT_MY_COLUMNS, oView, oControl)
' *** NEU: ConfigureViewColumnsCurrency() für editierbare Währungsspalten ***
oGridControlCreator.ConfigureViewColumnsCurrency(DT_MY_COLUMNS, oView, oControl)
oGridControlCreator.ConfigureViewEvents(DT_MY_COLUMNS, oView, oControl, oControlId) oGridControlCreator.ConfigureViewEvents(DT_MY_COLUMNS, oView, oControl, oControlId)
' 08.11.2021: Fix editor being empty on first open
oView.FocusInvalidRow() oView.FocusInvalidRow()
Return oControl Return oControl

View File

@@ -28,6 +28,60 @@ Public Class ClassFormat
End Select End Select
End Function End Function
''' <summary>
''' Normalisiert einen numerischen String für die invariante Kultur-Konvertierung.
''' Entfernt Tausendertrennzeichen und ersetzt Dezimaltrennzeichen durch Punkt.
''' </summary>
Private Shared Function NormalizeNumericString(pValue As String) As String
If String.IsNullOrWhiteSpace(pValue) Then
Return pValue
End If
Dim normalized As String = pValue.Trim()
' Entferne Währungssymbole und Leerzeichen
normalized = System.Text.RegularExpressions.Regex.Replace(normalized, "[€$£¥\s]", "")
' Prüfe, ob der String sowohl Punkt als auch Komma enthält
Dim hasDot As Boolean = normalized.Contains(".")
Dim hasComma As Boolean = normalized.Contains(",")
If hasDot AndAlso hasComma Then
' Beide vorhanden: Das letzte ist der Dezimaltrenner
Dim lastDotPos As Integer = normalized.LastIndexOf(".")
Dim lastCommaPos As Integer = normalized.LastIndexOf(",")
If lastDotPos > lastCommaPos Then
' Punkt ist Dezimaltrenner, Komma ist Tausendertrenner
normalized = normalized.Replace(",", "")
Else
' Komma ist Dezimaltrenner, Punkt ist Tausendertrenner
normalized = normalized.Replace(".", "").Replace(",", ".")
End If
ElseIf hasComma Then
' Nur Komma: Könnte Dezimal- oder Tausendertrenner sein
' Wenn mehr als ein Komma → Tausendertrenner
' Wenn nur ein Komma und <= 3 Stellen danach → Dezimaltrenner
Dim commaCount As Integer = normalized.Count(Function(c) c = ","c)
If commaCount = 1 Then
Dim lastCommaPos As Integer = normalized.LastIndexOf(",")
Dim digitsAfterComma As Integer = normalized.Length - lastCommaPos - 1
If digitsAfterComma <= 3 Then
' Wahrscheinlich Dezimaltrenner
normalized = normalized.Replace(",", ".")
Else
' Wahrscheinlich Tausendertrenner
normalized = normalized.Replace(",", "")
End If
Else
' Mehrere Kommas → Tausendertrenner
normalized = normalized.Replace(",", "")
End If
End If
' Wenn nur Punkt vorhanden: bereits im richtigen Format
Return normalized
End Function
''' <summary> ''' <summary>
''' Converts a string according to the type information, using the invariant culture ''' Converts a string according to the type information, using the invariant culture
@@ -41,25 +95,35 @@ Public Class ClassFormat
Select Case pType Select Case pType
Case ClassControlCreator.CONTROL_TYPE_DOUBLE Case ClassControlCreator.CONTROL_TYPE_DOUBLE
If Double.TryParse(pValue, NumberStyles.Float, CultureInfo.InvariantCulture, oConvertedValue) Then
Return oConvertedValue
End If
Case ClassControlCreator.CONTROL_TYPE_CURRENCY
Try Try
LOGGER.Debug($"GetConvertedValue: Converting {pValue.ToString} to Currency ") Dim normalizedValue As String = NormalizeNumericString(pValue?.ToString())
If Double.TryParse(pValue, NumberStyles.Currency, CultureInfo.InvariantCulture, oConvertedValue) Then If Double.TryParse(normalizedValue, NumberStyles.Float, CultureInfo.InvariantCulture, oConvertedValue) Then
Return oConvertedValue Return oConvertedValue
End If End If
Catch ex As Exception Catch ex As Exception
LOGGER.Error(ex) LOGGER.Error(ex)
End Try End Try
Case ClassControlCreator.CONTROL_TYPE_CURRENCY
Try
Dim normalizedValue As String = NormalizeNumericString(pValue?.ToString())
LOGGER.Debug($"GetConvertedValue: Converting {pValue.ToString} (normalized: {normalizedValue}) to Currency ")
If Double.TryParse(normalizedValue, NumberStyles.Float, CultureInfo.InvariantCulture, oConvertedValue) Then
Return oConvertedValue
End If
Catch ex As Exception
LOGGER.Error(ex)
End Try
Case ClassControlCreator.CONTROL_TYPE_INTEGER Case ClassControlCreator.CONTROL_TYPE_INTEGER
If Integer.TryParse(pValue, NumberStyles.Integer, CultureInfo.InvariantCulture, oConvertedValue) Then Try
Return oConvertedValue Dim normalizedValue As String = NormalizeNumericString(pValue?.ToString())
End If If Integer.TryParse(normalizedValue, NumberStyles.Integer, CultureInfo.InvariantCulture, oConvertedValue) Then
Return oConvertedValue
End If
Catch ex As Exception
LOGGER.Error(ex)
End Try
Case Else Case Else
LOGGER.Debug($"GetConvertedValue - Case ELSE - pType is {pType}") LOGGER.Debug($"GetConvertedValue - Case ELSE - pType is {pType}")
Try Try

View File

@@ -209,7 +209,7 @@
If IDB_USES_WMFILESTORE Then If IDB_USES_WMFILESTORE Then
oID_IS_FOREIGN = 1 oID_IS_FOREIGN = 1
End If End If
oTerm2Delete = oTerm2Delete.Replace("'", "''")
Dim oDELSQL = $"EXEC PRIDB_DELETE_TERM_OBJECT_METADATA {CURRENT_DOC_ID},'{oAttributeName}','{oTerm2Delete}','{USER_USERNAME}','{USER_LANGUAGE}',{oID_IS_FOREIGN};" Dim oDELSQL = $"EXEC PRIDB_DELETE_TERM_OBJECT_METADATA {CURRENT_DOC_ID},'{oAttributeName}','{oTerm2Delete}','{USER_USERNAME}','{USER_LANGUAGE}',{oID_IS_FOREIGN};"
LOGGER.Debug($"Delete_Term_Object_From_Metadata: {oDELSQL}") LOGGER.Debug($"Delete_Term_Object_From_Metadata: {oDELSQL}")
'DatabaseFallback.ExecuteNonQueryIDB(oDELSQL) 'DatabaseFallback.ExecuteNonQueryIDB(oDELSQL)
@@ -322,6 +322,7 @@
Return True Return True
Else Else
'oNewValue = oNewValue.Replace("'", "' + NCHAR(39) + '") 'oNewValue = oNewValue.Replace("'", "' + NCHAR(39) + '")
oNewValue = oNewValue.Replace("'", "''")
Dim oPRIDB_NEW_OBJ_DATA = $"DECLARE @NEW_OBJ_MD_ID BIGINT " & vbNewLine & $"EXEC PRIDB_NEW_OBJ_DATA {CURRENT_DOC_ID},'{oAttributeName}','{USER_USERNAME}','{oNewValue}','{USER_LANGUAGE}',0,@OMD_ID = @NEW_OBJ_MD_ID OUTPUT;" Dim oPRIDB_NEW_OBJ_DATA = $"DECLARE @NEW_OBJ_MD_ID BIGINT " & vbNewLine & $"EXEC PRIDB_NEW_OBJ_DATA {CURRENT_DOC_ID},'{oAttributeName}','{USER_USERNAME}','{oNewValue}','{USER_LANGUAGE}',0,@OMD_ID = @NEW_OBJ_MD_ID OUTPUT;"
LOGGER.Debug(oPRIDB_NEW_OBJ_DATA) LOGGER.Debug(oPRIDB_NEW_OBJ_DATA)
' Return DatabaseFallback.ExecuteNonQueryIDB(oPRIDB_NEW_OBJ_DATA) ' Return DatabaseFallback.ExecuteNonQueryIDB(oPRIDB_NEW_OBJ_DATA)

View File

@@ -27,10 +27,12 @@ Namespace ControlCreator
Private isApplyingInheritedValue As Boolean Private isApplyingInheritedValue As Boolean
Private _FormulaColumnNames As New HashSet(Of String)(StringComparer.OrdinalIgnoreCase) Private _FormulaColumnNames As New HashSet(Of String)(StringComparer.OrdinalIgnoreCase)
Private _isRefreshingFormula As Boolean = False ' *** NEU: Flag für Formel-Refresh *** Private _isRefreshingFormula As Boolean = False ' *** NEU: Flag für Formel-Refresh ***
Public Sub New(pLogConfig As LogConfig, pGridTables As Dictionary(Of Integer, Dictionary(Of String, RepositoryItem))) Private _currencySymbol As String = ""
Public Sub New(pLogConfig As LogConfig, pGridTables As Dictionary(Of Integer, Dictionary(Of String, RepositoryItem)), pCurrencySymbol As String)
_LogConfig = pLogConfig _LogConfig = pLogConfig
_Logger = pLogConfig.GetLogger() _Logger = pLogConfig.GetLogger()
_GridTables = pGridTables _GridTables = pGridTables
_currencySymbol = pCurrencySymbol
End Sub End Sub
Public Function CreateGridColumns(pColumnTable As DataTable) As DataTable Public Function CreateGridColumns(pColumnTable As DataTable) As DataTable
@@ -201,15 +203,15 @@ Namespace ControlCreator
End If End If
End Function End Function
' Hilfsroutine: passt NUR das Summary-Item an (ohne FormatInfo) ' Hilfsroutine: passt NUR das Summary-Item an (ohne FormatInfo)
Private Sub ApplyCurrencySummaryFormat(oCol As GridColumn, currencySymbol As String) Private Sub ApplyCurrencySummaryFormat(oCol As GridColumn)
oCol.SummaryItem.SummaryType = DevExpress.Data.SummaryItemType.Sum oCol.SummaryItem.SummaryType = DevExpress.Data.SummaryItemType.Sum
' Variante A: Standard-Währungsformat aus aktueller Kultur ' Variante A: Standard-Währungsformat aus aktueller Kultur
' oCol.SummaryItem.DisplayFormat = "SUM: {0:C2}" ' oCol.SummaryItem.DisplayFormat = "SUM: {0:C2}"
' Variante B: Kulturunabhängig, Symbol explizit anhängen ' Variante B: Kulturunabhängig, Symbol explizit anhängen
oCol.SummaryItem.DisplayFormat = $"SUM: {{0:N2}} {currencySymbol}" oCol.SummaryItem.DisplayFormat = $"SUM: {{0:N2}} {_currencySymbol}"
End Sub End Sub
Public Sub ConfigureViewColumns(pColumnTable As DataTable, pGridView As GridView, pGrid As DevExpress.XtraGrid.GridControl, pcurrencySymbol As String) Public Sub ConfigureViewColumns(pColumnTable As DataTable, pGridView As GridView, pGrid As DevExpress.XtraGrid.GridControl)
Dim oShouldDisplayFooter As Boolean = False Dim oShouldDisplayFooter As Boolean = False
For Each oCol As GridColumn In pGridView.Columns For Each oCol As GridColumn In pGridView.Columns
Dim oColumnData As DataRow = pColumnTable. Dim oColumnData As DataRow = pColumnTable.
@@ -255,7 +257,8 @@ Namespace ControlCreator
Case "CURRENCY" Case "CURRENCY"
oCol.DisplayFormat.FormatType = FormatType.Custom oCol.DisplayFormat.FormatType = FormatType.Custom
oCol.DisplayFormat.FormatString = "C2" oCol.DisplayFormat.FormatString = $"N2 {_currencySymbol}"
End Select End Select
Dim oSummaryFunction As String = oColumnData.Item("SUMMARY_FUNCTION") Dim oSummaryFunction As String = oColumnData.Item("SUMMARY_FUNCTION")
@@ -272,7 +275,7 @@ Namespace ControlCreator
oShouldDisplayFooter = True oShouldDisplayFooter = True
Case Constants.AGGREGATE_TOTAL_CURRENCY Case Constants.AGGREGATE_TOTAL_CURRENCY
ApplyCurrencySummaryFormat(oCol, pcurrencySymbol) ApplyCurrencySummaryFormat(oCol)
oShouldDisplayFooter = True oShouldDisplayFooter = True
Case Constants.AGGREGATE_TOTAL_AVG Case Constants.AGGREGATE_TOTAL_AVG
@@ -307,10 +310,10 @@ Namespace ControlCreator
End With End With
End If End If
End Sub End Sub
Public Sub ConfigureViewColumnsCurrency(pColumnTable As DataTable, pGridView As GridView, pGrid As DevExpress.XtraGrid.GridControl, pCurrency As String) Public Sub ConfigureViewColumnsCurrency(pColumnTable As DataTable, pGridView As GridView, pGrid As DevExpress.XtraGrid.GridControl)
Dim oCultureInfo As CultureInfo = New CultureInfo("de-DE") Dim oCultureInfo As CultureInfo = New CultureInfo("de-DE")
oCultureInfo.NumberFormat.CurrencySymbol = pCurrency oCultureInfo.NumberFormat.CurrencySymbol = _currencySymbol
Dim riTextEdit As RepositoryItemTextEdit = New RepositoryItemTextEdit() Dim riTextEdit As RepositoryItemTextEdit = New RepositoryItemTextEdit()
riTextEdit.MaskSettings.Configure(Of MaskSettings.Numeric)(Sub(settings) riTextEdit.MaskSettings.Configure(Of MaskSettings.Numeric)(Sub(settings)
settings.MaskExpression = "c" settings.MaskExpression = "c"
@@ -328,6 +331,12 @@ Namespace ControlCreator
Continue For Continue For
End If End If
' *** NEU: Prüfe ob Spalte editierbar ist ***
If Not oCol.OptionsColumn.AllowEdit Then
_Logger.Debug("Skipping ColumnEdit for read-only column [{0}]", oCol.FieldName)
Continue For
End If
' Formel-Spalten dürfen kein ColumnEdit bekommen, da der RepositoryItem-Cache ' Formel-Spalten dürfen kein ColumnEdit bekommen, da der RepositoryItem-Cache
' den berechneten Wert nach RefreshRowCell überschreibt. ' den berechneten Wert nach RefreshRowCell überschreibt.
Dim oFormulaExpression = ObjectEx.NotNull(oColumnData.Item("FORMULA_EXPRESSION"), String.Empty) Dim oFormulaExpression = ObjectEx.NotNull(oColumnData.Item("FORMULA_EXPRESSION"), String.Empty)
@@ -340,7 +349,7 @@ Namespace ControlCreator
Select Case oColumnType Select Case oColumnType
Case "CURRENCY" Case "CURRENCY"
oCol.DisplayFormat.FormatType = FormatType.Custom ' *** WICHTIG: NUR ColumnEdit setzen, KEIN DisplayFormat mehr! ***
oCol.ColumnEdit = riTextEdit oCol.ColumnEdit = riTextEdit
End Select End Select
Next Next
@@ -380,6 +389,55 @@ Namespace ControlCreator
newRowModified = False newRowModified = False
End Try End Try
End Sub End Sub
' *** NEU: CustomColumnDisplayText für robuste CURRENCY-Formatierung ***
AddHandler pGridView.CustomColumnDisplayText,
Sub(sender As Object, e As CustomColumnDisplayTextEventArgs)
If e.Column Is Nothing OrElse e.Value Is Nothing OrElse IsDBNull(e.Value) Then
Return
End If
' Prüfe ob Spalte vom Typ CURRENCY ist
Dim oColumnData As DataRow = pColumnTable.
Select($"SPALTENNAME = '{e.Column.FieldName}'").
FirstOrDefault()
If oColumnData IsNot Nothing AndAlso
oColumnData.Item("TYPE_COLUMN").ToString() = "CURRENCY" Then
Try
Dim oValue As Double
' *** KRITISCH: Robustes Parsing unabhängig vom Dezimaltrenner ***
If TypeOf e.Value Is Double OrElse TypeOf e.Value Is Decimal Then
oValue = Convert.ToDouble(e.Value)
ElseIf TypeOf e.Value Is String Then
Dim oStringValue As String = e.Value.ToString().Trim()
' Versuche zuerst deutsches Format (1.234,56)
Dim oDeCulture As CultureInfo = New CultureInfo("de-DE")
If Double.TryParse(oStringValue, NumberStyles.Currency Or NumberStyles.Number, oDeCulture, oValue) Then
' Erfolgreich mit deutschem Format geparst
ElseIf Double.TryParse(oStringValue, NumberStyles.Currency Or NumberStyles.Number, CultureInfo.InvariantCulture, oValue) Then
' Erfolgreich mit invariantem Format (Punkt als Dezimaltrenner)
Else
' Fallback: Systemkultur
oValue = Convert.ToDouble(oStringValue, CultureInfo.CurrentCulture)
End If
Else
oValue = Convert.ToDouble(e.Value)
End If
' Formatierung IMMER mit deutscher Kultur (Komma als Dezimaltrenner)
Dim oDeCultureInfo As CultureInfo = New CultureInfo("de-DE")
e.DisplayText = oValue.ToString("N2", oDeCultureInfo) & " " & _currencySymbol
Catch ex As Exception
_Logger.Warn("⚠️ Could not format currency value [{0}] for column [{1}]: {2}",
e.Value, e.Column.FieldName, ex.Message)
' Fallback: Original-Wert + Symbol
e.DisplayText = e.Value.ToString() & " " & _currencySymbol
End Try
End If
End Sub
AddHandler pGridView.CustomRowCellEdit, Sub(sender As Object, e As CustomRowCellEditEventArgs) AddHandler pGridView.CustomRowCellEdit, Sub(sender As Object, e As CustomRowCellEditEventArgs)
Try Try
@@ -800,16 +858,7 @@ Namespace ControlCreator
Return entry Return entry
End Function End Function
Private Sub View_CustomColumnDisplayText(ByVal eSender As Object, ByVal e As CustomColumnDisplayTextEventArgs)
If IsNothing(e.Value) Then
Exit Sub
End If
Dim view As GridView = eSender
'Dim view As GridView = TryCast(GridView1, GridView)
If e.Column.FieldName = "SpalteCurrency" Then
' e.DisplayText = e.Value.ToString().Replace("€", "CHF")
End If
End Sub
Private Sub View_PopupMenuShowing(sender As Object, e As PopupMenuShowingEventArgs) Private Sub View_PopupMenuShowing(sender As Object, e As PopupMenuShowingEventArgs)
Dim view As GridView = TryCast(sender, GridView) Dim view As GridView = TryCast(sender, GridView)
Dim oFocusedColumn As GridColumn = view.FocusedColumn Dim oFocusedColumn As GridColumn = view.FocusedColumn

View File

@@ -13,7 +13,7 @@ Imports System.Runtime.InteropServices
<Assembly: AssemblyDescription("")> <Assembly: AssemblyDescription("")>
<Assembly: AssemblyCompany("Digital Data")> <Assembly: AssemblyCompany("Digital Data")>
<Assembly: AssemblyProduct("taskFLOW")> <Assembly: AssemblyProduct("taskFLOW")>
<Assembly: AssemblyCopyright("Copyright © Digital Data 2025")> <Assembly: AssemblyCopyright("Digital Data 2026")>
<Assembly: AssemblyTrademark("")> <Assembly: AssemblyTrademark("")>
<Assembly: ComVisible(False)> <Assembly: ComVisible(False)>
@@ -32,6 +32,6 @@ Imports System.Runtime.InteropServices
' übernehmen, indem Sie "*" eingeben: ' übernehmen, indem Sie "*" eingeben:
' <Assembly: AssemblyVersion("1.0.*")> ' <Assembly: AssemblyVersion("1.0.*")>
<Assembly: AssemblyVersion("2.8.3.0")> <Assembly: AssemblyVersion("2.8.4.0")>
<Assembly: AssemblyFileVersion("1.0.0.0")> <Assembly: AssemblyFileVersion("1.0.0.0")>
<Assembly: NeutralResourcesLanguage("")> <Assembly: NeutralResourcesLanguage("")>

View File

@@ -125,7 +125,7 @@
AAEAAAD/////AQAAAAAAAAAMAgAAAFdTeXN0ZW0uV2luZG93cy5Gb3JtcywgVmVyc2lvbj00LjAuMC4w AAEAAAD/////AQAAAAAAAAAMAgAAAFdTeXN0ZW0uV2luZG93cy5Gb3JtcywgVmVyc2lvbj00LjAuMC4w
LCBDdWx0dXJlPW5ldXRyYWwsIFB1YmxpY0tleVRva2VuPWI3N2E1YzU2MTkzNGUwODkFAQAAACZTeXN0 LCBDdWx0dXJlPW5ldXRyYWwsIFB1YmxpY0tleVRva2VuPWI3N2E1YzU2MTkzNGUwODkFAQAAACZTeXN0
ZW0uV2luZG93cy5Gb3Jtcy5JbWFnZUxpc3RTdHJlYW1lcgEAAAAERGF0YQcCAgAAAAkDAAAADwMAAADw ZW0uV2luZG93cy5Gb3Jtcy5JbWFnZUxpc3RTdHJlYW1lcgEAAAAERGF0YQcCAgAAAAkDAAAADwMAAADw
CAAAAk1TRnQBSQFMAgEBAgEAAcgBCwHIAQsBEAEAARABAAT/AQkBAAj/AUIBTQE2AQQGAAE2AQQCAAEo CAAAAk1TRnQBSQFMAgEBAgEAAfABCwHwAQsBEAEAARABAAT/AQkBAAj/AUIBTQE2AQQGAAE2AQQCAAEo
AwABQAMAARADAAEBAQABCAYAAQQYAAGAAgABgAMAAoABAAGAAwABgAEAAYABAAKAAgADwAEAAcAB3AHA AwABQAMAARADAAEBAQABCAYAAQQYAAGAAgABgAMAAoABAAGAAwABgAEAAYABAAKAAgADwAEAAcAB3AHA
AQAB8AHKAaYBAAEzBQABMwEAATMBAAEzAQACMwIAAxYBAAMcAQADIgEAAykBAANVAQADTQEAA0IBAAM5 AQAB8AHKAaYBAAEzBQABMwEAATMBAAEzAQACMwIAAxYBAAMcAQADIgEAAykBAANVAQADTQEAA0IBAAM5
AQABgAF8Af8BAAJQAf8BAAGTAQAB1gEAAf8B7AHMAQABxgHWAe8BAAHWAucBAAGQAakBrQIAAf8BMwMA AQABgAF8Af8BAAJQAf8BAAGTAQAB1gEAAf8B7AHMAQABxgHWAe8BAAHWAucBAAGQAakBrQIAAf8BMwMA
@@ -1496,36 +1496,9 @@
<data name="RibbonControl1.Location" type="System.Drawing.Point, System.Drawing"> <data name="RibbonControl1.Location" type="System.Drawing.Point, System.Drawing">
<value>0, 0</value> <value>0, 0</value>
</data> </data>
<data name="RibbonPageGroup1.Text" xml:space="preserve">
<value>Allgemein</value>
</data>
<data name="RibbonPageGroup2.Text" xml:space="preserve">
<value>Auswertungen</value>
</data>
<data name="RibbonPageGroup3.Text" xml:space="preserve">
<value>Verwaltung</value>
</data>
<data name="RibbonPageGroupBasicConf.Text" xml:space="preserve">
<value>Grundeinstellungen</value>
</data>
<data name="RibbonPageGroup7.Text" xml:space="preserve">
<value>Workflow</value>
</data>
<data name="RibbonPageGroup4.Text" xml:space="preserve">
<value>Funktionen/App Start</value>
</data>
<data name="RibbonPageGroupAHW.Text" xml:space="preserve">
<value>Ad Hoc Workflows</value>
</data>
<data name="RibbonPageStart.Text" xml:space="preserve"> <data name="RibbonPageStart.Text" xml:space="preserve">
<value>Start</value> <value>Start</value>
</data> </data>
<data name="RibbonPageGroup6.Text" xml:space="preserve">
<value>Funktionen</value>
</data>
<data name="RibbonPageGroup5.Text" xml:space="preserve">
<value>Workflow Tabelle</value>
</data>
<data name="RibbonPageTabelle.Text" xml:space="preserve"> <data name="RibbonPageTabelle.Text" xml:space="preserve">
<value>Tabelle</value> <value>Tabelle</value>
</data> </data>
@@ -1583,24 +1556,6 @@
<data name="&gt;&gt;GridControlWorkflows.ZOrder" xml:space="preserve"> <data name="&gt;&gt;GridControlWorkflows.ZOrder" xml:space="preserve">
<value>0</value> <value>0</value>
</data> </data>
<data name="lblCaptionMainGrid.AutoSize" type="System.Boolean, mscorlib">
<value>True</value>
</data>
<data name="lblCaptionMainGrid.Font" type="System.Drawing.Font, System.Drawing">
<value>Tahoma, 9.75pt, style=Bold</value>
</data>
<data name="lblCaptionMainGrid.Location" type="System.Drawing.Point, System.Drawing">
<value>3, 3</value>
</data>
<data name="lblCaptionMainGrid.Size" type="System.Drawing.Size, System.Drawing">
<value>127, 16</value>
</data>
<data name="lblCaptionMainGrid.TabIndex" type="System.Int32, mscorlib">
<value>0</value>
</data>
<data name="lblCaptionMainGrid.Text" xml:space="preserve">
<value>Choose a profile ...</value>
</data>
<data name="&gt;&gt;lblCaptionMainGrid.Name" xml:space="preserve"> <data name="&gt;&gt;lblCaptionMainGrid.Name" xml:space="preserve">
<value>lblCaptionMainGrid</value> <value>lblCaptionMainGrid</value>
</data> </data>
@@ -1692,12 +1647,6 @@
<metadata name="cmsNavPane.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a"> <metadata name="cmsNavPane.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
<value>863, 17</value> <value>863, 17</value>
</metadata> </metadata>
<data name="tsmiValidationProfil.Size" type="System.Drawing.Size, System.Drawing">
<value>219, 26</value>
</data>
<data name="tsmiValidationProfil.Text" xml:space="preserve">
<value>Starte Validierung für Profil</value>
</data>
<data name="cmsNavPane.Size" type="System.Drawing.Size, System.Drawing"> <data name="cmsNavPane.Size" type="System.Drawing.Size, System.Drawing">
<value>220, 30</value> <value>220, 30</value>
</data> </data>
@@ -1880,6 +1829,69 @@
<data name="&gt;&gt;Panel1.ZOrder" xml:space="preserve"> <data name="&gt;&gt;Panel1.ZOrder" xml:space="preserve">
<value>2</value> <value>2</value>
</data> </data>
<data name="RibbonPageGroup1.Text" xml:space="preserve">
<value>Allgemein</value>
</data>
<data name="RibbonPageGroup2.Text" xml:space="preserve">
<value>Auswertungen</value>
</data>
<data name="RibbonPageGroup3.Text" xml:space="preserve">
<value>Verwaltung</value>
</data>
<data name="RibbonPageGroupBasicConf.Text" xml:space="preserve">
<value>Grundeinstellungen</value>
</data>
<data name="RibbonPageGroup7.Text" xml:space="preserve">
<value>Workflow</value>
</data>
<data name="RibbonPageGroup4.Text" xml:space="preserve">
<value>Funktionen/App Start</value>
</data>
<data name="RibbonPageGroupAHW.Text" xml:space="preserve">
<value>Ad Hoc Workflows</value>
</data>
<data name="RibbonPageGroup6.Text" xml:space="preserve">
<value>Funktionen</value>
</data>
<data name="RibbonPageGroup5.Text" xml:space="preserve">
<value>Workflow Tabelle</value>
</data>
<data name="lblCaptionMainGrid.AutoSize" type="System.Boolean, mscorlib">
<value>True</value>
</data>
<data name="lblCaptionMainGrid.Font" type="System.Drawing.Font, System.Drawing">
<value>Tahoma, 9.75pt, style=Bold</value>
</data>
<data name="lblCaptionMainGrid.Location" type="System.Drawing.Point, System.Drawing">
<value>3, 3</value>
</data>
<data name="lblCaptionMainGrid.Size" type="System.Drawing.Size, System.Drawing">
<value>127, 16</value>
</data>
<data name="lblCaptionMainGrid.TabIndex" type="System.Int32, mscorlib">
<value>0</value>
</data>
<data name="lblCaptionMainGrid.Text" xml:space="preserve">
<value>Choose a profile ...</value>
</data>
<data name="&gt;&gt;lblCaptionMainGrid.Name" xml:space="preserve">
<value>lblCaptionMainGrid</value>
</data>
<data name="&gt;&gt;lblCaptionMainGrid.Type" xml:space="preserve">
<value>System.Windows.Forms.Label, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</data>
<data name="&gt;&gt;lblCaptionMainGrid.Parent" xml:space="preserve">
<value>Panel2</value>
</data>
<data name="&gt;&gt;lblCaptionMainGrid.ZOrder" xml:space="preserve">
<value>0</value>
</data>
<data name="tsmiValidationProfil.Size" type="System.Drawing.Size, System.Drawing">
<value>219, 26</value>
</data>
<data name="tsmiValidationProfil.Text" xml:space="preserve">
<value>Starte Validierung für Profil</value>
</data>
<metadata name="bindsourcegrid.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a"> <metadata name="bindsourcegrid.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
<value>986, 17</value> <value>986, 17</value>
</metadata> </metadata>
@@ -1889,27 +1901,6 @@
<metadata name="ContextMenuNotifyIcon.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a"> <metadata name="ContextMenuNotifyIcon.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
<value>1220, 17</value> <value>1220, 17</value>
</metadata> </metadata>
<data name="PopupErinnerungInaktivierenToolStripMenuItem.Size" type="System.Drawing.Size, System.Drawing">
<value>290, 30</value>
</data>
<data name="PopupErinnerungInaktivierenToolStripMenuItem.Text" xml:space="preserve">
<value>Popup Erinnerung deaktivieren</value>
</data>
<data name="ToolStripSeparator1.Size" type="System.Drawing.Size, System.Drawing">
<value>287, 6</value>
</data>
<data name="AnzeigenToolStripMenuItem.Size" type="System.Drawing.Size, System.Drawing">
<value>290, 30</value>
</data>
<data name="AnzeigenToolStripMenuItem.Text" xml:space="preserve">
<value>In den Vordergrund</value>
</data>
<data name="OutOfRangePMFixierenToolStripMenuItem.Size" type="System.Drawing.Size, System.Drawing">
<value>290, 30</value>
</data>
<data name="OutOfRangePMFixierenToolStripMenuItem.Text" xml:space="preserve">
<value>Out of Range - Fenster wiederherstellen</value>
</data>
<data name="ContextMenuNotifyIcon.Size" type="System.Drawing.Size, System.Drawing"> <data name="ContextMenuNotifyIcon.Size" type="System.Drawing.Size, System.Drawing">
<value>291, 100</value> <value>291, 100</value>
</data> </data>
@@ -2005,6 +1996,27 @@
<data name="NotifyIcon1.Visible" type="System.Boolean, mscorlib"> <data name="NotifyIcon1.Visible" type="System.Boolean, mscorlib">
<value>True</value> <value>True</value>
</data> </data>
<data name="PopupErinnerungInaktivierenToolStripMenuItem.Size" type="System.Drawing.Size, System.Drawing">
<value>290, 30</value>
</data>
<data name="PopupErinnerungInaktivierenToolStripMenuItem.Text" xml:space="preserve">
<value>Popup Erinnerung deaktivieren</value>
</data>
<data name="ToolStripSeparator1.Size" type="System.Drawing.Size, System.Drawing">
<value>287, 6</value>
</data>
<data name="AnzeigenToolStripMenuItem.Size" type="System.Drawing.Size, System.Drawing">
<value>290, 30</value>
</data>
<data name="AnzeigenToolStripMenuItem.Text" xml:space="preserve">
<value>In den Vordergrund</value>
</data>
<data name="OutOfRangePMFixierenToolStripMenuItem.Size" type="System.Drawing.Size, System.Drawing">
<value>290, 30</value>
</data>
<data name="OutOfRangePMFixierenToolStripMenuItem.Text" xml:space="preserve">
<value>Out of Range - Fenster wiederherstellen</value>
</data>
<metadata name="TimerRefresh.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a"> <metadata name="TimerRefresh.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
<value>605, 17</value> <value>605, 17</value>
</metadata> </metadata>
@@ -3432,6 +3444,9 @@
<data name="miView.Caption" xml:space="preserve"> <data name="miView.Caption" xml:space="preserve">
<value>&amp;Ansicht</value> <value>&amp;Ansicht</value>
</data> </data>
<data name="miBackground.Caption" xml:space="preserve">
<value>&amp;Hintergrund</value>
</data>
<data name="miPageLayout.Caption" xml:space="preserve"> <data name="miPageLayout.Caption" xml:space="preserve">
<value>&amp;Seiten Layout</value> <value>&amp;Seiten Layout</value>
</data> </data>
@@ -3444,9 +3459,6 @@
<data name="miToolbars.Caption" xml:space="preserve"> <data name="miToolbars.Caption" xml:space="preserve">
<value>Bars</value> <value>Bars</value>
</data> </data>
<data name="miBackground.Caption" xml:space="preserve">
<value>&amp;Hintergrund</value>
</data>
<data name="PrintPreviewBarCheckItem1.Caption" xml:space="preserve"> <data name="PrintPreviewBarCheckItem1.Caption" xml:space="preserve">
<value>PDF Dokument</value> <value>PDF Dokument</value>
</data> </data>

View File

@@ -1977,6 +1977,8 @@ Public Class frmMain
Dim useWaitCursorApplied As Boolean = False Dim useWaitCursorApplied As Boolean = False
Dim previousMessage As String = bsiMessage.Caption Dim previousMessage As String = bsiMessage.Caption
Dim messageApplied As Boolean = False Dim messageApplied As Boolean = False
Dim oHandle As Object = Nothing
Dim overlayStartedHere As Boolean = False
If LOG_HOTSPOTS Then If LOG_HOTSPOTS Then
perfStart = DateTime.Now perfStart = DateTime.Now
@@ -1987,6 +1989,14 @@ Public Class frmMain
CURRENT_ProfilGUID = pProfilID CURRENT_ProfilGUID = pProfilID
WM_AHWF_docPath = String.Empty WM_AHWF_docPath = String.Empty
' ========== OVERLAY ANZEIGEN ==========
If Not _overlayActive Then
oHandle = SplashScreenManager.ShowOverlayForm(Me)
_overlayActive = True
overlayStartedHere = True
End If
' ========== UI-VORBEREITUNG ========== ' ========== UI-VORBEREITUNG ==========
Me.UseWaitCursor = True Me.UseWaitCursor = True
useWaitCursorApplied = True useWaitCursorApplied = True
@@ -2091,6 +2101,13 @@ Public Class frmMain
MsgBox("Unexpected error in Load_Profil_from_Grid: " & ex.Message & vbNewLine & ADDITIONAL_TITLE & " will try to reload the overview - Please try again!", MsgBoxStyle.Information, ADDITIONAL_TITLE) MsgBox("Unexpected error in Load_Profil_from_Grid: " & ex.Message & vbNewLine & ADDITIONAL_TITLE & " will try to reload the overview - Please try again!", MsgBoxStyle.Information, ADDITIONAL_TITLE)
Dim task = Decide_Load(False, True) Dim task = Decide_Load(False, True)
Finally Finally
' ========== OVERLAY SCHLIESSEN (FALLBACK) ==========
If overlayStartedHere AndAlso _overlayActive Then
SplashScreenManager.CloseOverlayForm(oHandle)
LOGGER.Debug("Overlay closed in Load_Profil_from_Grid")
_overlayActive = False
End If
' ========== UI AUFRÄUMEN ========== ' ========== UI AUFRÄUMEN ==========
If useWaitCursorApplied Then If useWaitCursorApplied Then
Me.UseWaitCursor = False Me.UseWaitCursor = False

View File

@@ -135,9 +135,10 @@ Public Class frmValidator
Private _CachedControlsByGuid As Dictionary(Of Integer, Control) Private _CachedControlsByGuid As Dictionary(Of Integer, Control)
Private _isUpdatingLookup As Boolean = False Private _isUpdatingLookup As Boolean = False
Private _suppressLookupEvents As Boolean = False Private _suppressLookupEvents As Boolean = False
Private _overlayActive As Boolean = False
Private _isShowingErrorDialog As Boolean = False ' ← NEU: Klassenvariable oben hinzufügen Private _isShowingErrorDialog As Boolean = False ' ← NEU: Klassenvariable oben hinzufügen
Private _overlayHandle As Object = Nothing ' ← NEU: Klassenvariable Private _overlayHandle As Object = Nothing ' ← NEU: Klassenvariable
Private _overlayRefCount As Integer = 0 ' ← NEU: Zähler für verschachtelte Calls
Private _overlayLock As New Object() ' ← NEU: Thread-Safe Lock
Private Class Translation_Strings Private Class Translation_Strings
@@ -163,7 +164,70 @@ Public Class frmValidator
End Sub End Sub
' ========== NEU: Zentrale Overlay-Verwaltung ==========
''' <summary>
''' Thread-sicheres Öffnen des Overlays (verschachtelte Calls werden ignoriert)
''' </summary>
Private Function ShowOverlaySafe() As Boolean
SyncLock _overlayLock
If _overlayRefCount = 0 Then
Try
_overlayHandle = SplashScreenManager.ShowOverlayForm(Me)
MyValidationLogger.Debug($"[Overlay] Geöffnet (RefCount: 0 → 1)")
Catch ex As Exception
MyValidationLogger.Error($"[Overlay] Fehler beim Öffnen: {ex.Message}")
Return False
End Try
Else
MyValidationLogger.Debug($"[Overlay] Bereits offen (RefCount: {_overlayRefCount} → {_overlayRefCount + 1})")
End If
_overlayRefCount += 1
Return True
End SyncLock
End Function
''' <summary>
''' Thread-sicheres Schließen des Overlays (nur wenn RefCount = 0)
''' </summary>
Private Sub CloseOverlaySafe()
SyncLock _overlayLock
If _overlayRefCount > 0 Then
_overlayRefCount -= 1
MyValidationLogger.Debug($"[Overlay] RefCount: {_overlayRefCount + 1} → {_overlayRefCount}")
End If
If _overlayRefCount = 0 AndAlso _overlayHandle IsNot Nothing Then
Try
SplashScreenManager.CloseOverlayForm(_overlayHandle)
MyValidationLogger.Debug("[Overlay] ✓ Geschlossen")
Catch ex As Exception
MyValidationLogger.Warn($"[Overlay] Fehler beim Schließen: {ex.Message}")
Finally
_overlayHandle = Nothing
End Try
End If
End SyncLock
End Sub
''' <summary>
''' Erzwingt sofortiges Schließen (nur für Fehlerfall / FormClosing)
''' </summary>
Private Sub ForceCloseOverlay()
SyncLock _overlayLock
If _overlayHandle IsNot Nothing Then
Try
SplashScreenManager.CloseOverlayForm(_overlayHandle)
MyValidationLogger.Debug("[Overlay] ⚠️ FORCE CLOSED")
Catch ex As Exception
MyValidationLogger.Warn($"[Overlay] Force-Close failed: {ex.Message}")
Finally
_overlayHandle = Nothing
_overlayRefCount = 0
End Try
End If
End SyncLock
End Sub
' ========== ENDE NEU ==========
Private Function GetOperationMode() As OperationMode Private Function GetOperationMode() As OperationMode
Dim oOperationMode As OperationMode Dim oOperationMode As OperationMode
@@ -2015,6 +2079,11 @@ Public Class frmValidator
End Try End Try
End Sub End Sub
Private Sub GridView_CellValueChanged(sender As Object, e As DevExpress.XtraGrid.Views.Base.CellValueChangedEventArgs) Private Sub GridView_CellValueChanged(sender As Object, e As DevExpress.XtraGrid.Views.Base.CellValueChangedEventArgs)
' Prevent cascading events during validation
If _isShowingErrorDialog Then
MyValidationLogger.Debug("GridView_CellValueChanged suppressed (currently showing error dialog)")
Return
End If
Dim oView As GridView = sender Dim oView As GridView = sender
Dim oGrid As GridControl = oView.GridControl Dim oGrid As GridControl = oView.GridControl
Dim oMeta As ClassControlCreator.ControlMetadata = oGrid.Tag Dim oMeta As ClassControlCreator.ControlMetadata = oGrid.Tag
@@ -2439,7 +2508,10 @@ Public Class frmValidator
Catch ex As Exception Catch ex As Exception
MyValidationLogger.Error(ex) MyValidationLogger.Error(ex)
MyValidationLogger.Warn($"⚠️ Error while Control2Set for [{oControlname2Set}]: " & ex.Message) MyValidationLogger.Warn($"⚠️ SetControlValues_FromControl - Error in SetControlValues_FromControl for control [{pControl?.Name}]: {ex.Message}")
' WICHTIG: Overlay schließen bei Fehler
CloseOverlaySafe()
Finally Finally
_SetControlValue_In_Action = False _SetControlValue_In_Action = False
End Try End Try
@@ -2806,6 +2878,12 @@ Public Class frmValidator
End Sub End Sub
Public Sub OnCmbselectedIndex(sender As System.Object, e As System.EventArgs) Public Sub OnCmbselectedIndex(sender As System.Object, e As System.EventArgs)
' Prevent cascading events during validation
If _isShowingErrorDialog Then
MyValidationLogger.Debug($"OnCmbselectedIndex: Currently showing error dialog, skipping event handling to prevent cascade.")
Return
End If
Dim oCombobox As Windows.Forms.ComboBox = sender Dim oCombobox As Windows.Forms.ComboBox = sender
If oCombobox.SelectedIndex <> -1 And _Indexe_Loaded = True Then If oCombobox.SelectedIndex <> -1 And _Indexe_Loaded = True Then
Dim oMeta As ClassControlCreator.ControlMetadata = oCombobox.Tag Dim oMeta As ClassControlCreator.ControlMetadata = oCombobox.Tag
@@ -3261,34 +3339,55 @@ Public Class frmValidator
Private Function CreateWMObject() As String Private Function CreateWMObject() As Boolean
MyValidationLogger.Debug($"in GetWMDocFileString...'")
Dim oWMOwnPath As String Dim oWMOwnPath As String
If WM_AHWF_docPath <> String.Empty Then
oWMOwnPath = WM_AHWF_docPath
WMDocPathWindows = oWMOwnPath
Else
oWMOwnPath = WMDocPathWindows.Replace(WMSUFFIX, "")
End If
MyValidationLogger.Debug($"oWMOwnPath: {oWMOwnPath}")
Try Try
Dim oNormalizedPath = WINDREAM_MOD.GetNormalizedPath(oWMOwnPath, 1) MyValidationLogger.Debug($"in GetWMDocFileString...'")
CURRENT_WMFILE = WINDREAM_MOD.Session.GetWMObjectByPath(WMEntity.WMEntityDocument, oNormalizedPath)
MyValidationLogger.Debug("CURRENT_WMFILE: [{0}]", CURRENT_WMFILE)
Return True If WM_AHWF_docPath <> String.Empty Then
oWMOwnPath = WM_AHWF_docPath
WMDocPathWindows = oWMOwnPath
Else
oWMOwnPath = WMDocPathWindows.Replace(WMSUFFIX, "")
End If
Try
Dim oNormalizedPath = WINDREAM_MOD.GetNormalizedPath(oWMOwnPath, 1)
CURRENT_WMFILE = WINDREAM_MOD.Session.GetWMObjectByPath(WMEntity.WMEntityDocument, oNormalizedPath)
MyValidationLogger.Debug("CURRENT_WMFILE: [{0}]", CURRENT_WMFILE)
Return True ' ← Erfolg
Catch comEx As System.Runtime.InteropServices.COMException
' ========== OPTIMIERT: Detaillierte COM-Fehlerbehandlung ==========
MyValidationLogger.Error($"COM-Fehler HRESULT: {comEx.ErrorCode:X8}, Pfad: [{oWMOwnPath}]")
Select Case comEx.ErrorCode
Case &H8004C005 ' Objekt nicht gefunden
errormessage = $"Dokument [{oWMOwnPath}] existiert nicht in windream!"
Case &H80040E14 ' Zugriff verweigert
errormessage = $"Keine Berechtigung für [{oWMOwnPath}]!"
Case Else
errormessage = $"windream-Fehler: {comEx.Message}"
End Select
' ========== FIX 2: OpenfrmError() statt frmError.ShowDialog() ==========
OpenfrmError(errormessage)
' ========== ENDE FIX 2 ==========
Return False ' ← Fehler
End Try
Catch ex As Exception Catch ex As Exception
Dim _err1 As Boolean = False
MyValidationLogger.Error(ex) MyValidationLogger.Error(ex)
MyValidationLogger.Info("Unexpected error creating WMObject(1) in GetWMDocFileString: " & ex.Message) MyValidationLogger.Info("Unexpected error creating WMObject(1) in GetWMDocFileString: " & ex.Message)
MyValidationLogger.Info("Error Number: " & Err.Number.ToString) MyValidationLogger.Info("Error Number: " & Err.Number.ToString)
errormessage = $"Could not create a WMObject(1) for [{oWMOwnPath}]!" errormessage = $"Could not create a WMObject(1) for [{oWMOwnPath}]!"
frmError.ShowDialog() ' ========== FIX 4: Auch hier OpenfrmError() verwenden ==========
OpenfrmError(errormessage)
Return False Return False
' ========== ENDE FIX 4 ==========
End Try End Try
End Function End Function
Private Function GetDocPathWindows(_CheckStandard As Integer) Private Function GetDocPathWindows(_CheckStandard As Integer)
Try Try
@@ -3377,7 +3476,6 @@ Public Class frmValidator
Dim oMilliseconts As Double Dim oMilliseconts As Double
clsPatterns.ClearControlCache() ' Cache-Invalidierung clsPatterns.ClearControlCache() ' Cache-Invalidierung
Dim perfStart As DateTime = DateTime.MinValue Dim perfStart As DateTime = DateTime.MinValue
Dim perfLastCheck As DateTime = DateTime.MinValue Dim perfLastCheck As DateTime = DateTime.MinValue
If LOG_HOTSPOTS Then If LOG_HOTSPOTS Then
@@ -3676,6 +3774,7 @@ Public Class frmValidator
End If End If
MyValidationLogger.Debug("frmValidator: LoadNextDocument finished!") MyValidationLogger.Debug("frmValidator: LoadNextDocument finished!")
Catch ex As Exception Catch ex As Exception
MyValidationLogger.Error(ex) MyValidationLogger.Error(ex)
errormessage = "unexpected error in Load_Next_Document:" & ex.Message errormessage = "unexpected error in Load_Next_Document:" & ex.Message
@@ -3686,7 +3785,6 @@ Public Class frmValidator
If layoutSuspended Then If layoutSuspended Then
PanelValidatorControl.ResumeLayout() PanelValidatorControl.ResumeLayout()
End If End If
If LOG_HOTSPOTS Then If LOG_HOTSPOTS Then
' ========== DIAGNOSE ENDE ========== ' ========== DIAGNOSE ENDE ==========
MyValidationLogger.Info($"[INFO] Load_Next_Document ENDE") MyValidationLogger.Info($"[INFO] Load_Next_Document ENDE")
@@ -5089,7 +5187,7 @@ Public Class frmValidator
End Sub End Sub
Private Sub frmValidation_Shown(sender As Object, e As System.EventArgs) Handles Me.Shown Private Sub frmValidation_Shown(sender As Object, e As System.EventArgs) Handles Me.Shown
Dim oHandle = SplashScreenManager.ShowOverlayForm(Me) ShowOverlaySafe()
Dim perfStart As DateTime = DateTime.MinValue Dim perfStart As DateTime = DateTime.MinValue
Dim perfLastCheck As DateTime = DateTime.MinValue Dim perfLastCheck As DateTime = DateTime.MinValue
If LOG_HOTSPOTS Then If LOG_HOTSPOTS Then
@@ -5185,49 +5283,69 @@ Public Class frmValidator
End If End If
MyValidationLogger.Debug("frmValidation_Shown finished!") MyValidationLogger.Debug("frmValidation_Shown finished!")
' ✅ Overlay explizit schließen
Try
If SplashScreenManager.Default IsNot Nothing AndAlso SplashScreenManager.Default.IsSplashFormVisible Then
SplashScreenManager.CloseForm(False)
MyValidationLogger.Debug("✓ Overlay closed in frmValidation_Shown")
Else
MyValidationLogger.Debug(" Overlay war bereits geschlossen")
End If
' ✅ UI-Refresh erzwingen
Application.DoEvents()
Me.Refresh()
Catch ex As Exception
MyValidationLogger.Error($"❌ Error closing overlay in Shown: {ex.Message}")
End Try
If LOG_HOTSPOTS Then If LOG_HOTSPOTS Then
MyValidationLogger.Info($"[PERF] frmValidation_Shown GESAMT: {(DateTime.Now - perfStart).TotalMilliseconds}ms") MyValidationLogger.Info($"[PERF] frmValidation_Shown GESAMT: {(DateTime.Now - perfStart).TotalMilliseconds}ms")
End If End If
Finally Finally
SplashScreenManager.CloseOverlayForm(oHandle) CloseOverlaySafe()
' ✅ UI-Refresh erzwingen
Try
Application.DoEvents()
Me.Refresh()
Me.BringToFront()
Catch ex As Exception
MyValidationLogger.Error($"❌ Error in UI refresh: {ex.Message}")
End Try
End Try End Try
Try
' Alle offenen Forms durchsuchen
For Each frm As Form In Application.OpenForms
If frm.GetType().FullName.StartsWith("DevExpress.XtraSplashScreen") Then
MyValidationLogger.Warn($"⚠️ Unerwartete SplashForm gefunden: {frm.Name}")
frm.Close()
End If
Next
Catch ex As Exception
MyValidationLogger.Error($"Error checking for splash forms: {ex.Message}")
End Try
End Sub End Sub
Private Sub btnSave_Click(sender As Object, e As EventArgs) Handles btnSave.Click Private Sub btnSave_Click(sender As Object, e As EventArgs) Handles btnSave.Click
' ========== FIX 1: Button-State-Management ==========
If btnSave.Enabled = False Then If btnSave.Enabled = False Then
MyValidationLogger.Warn("btnSave_Click: Button bereits disabled, Exit Sub") MyValidationLogger.Warn("btnSave_Click: Button bereits disabled, Exit Sub")
Exit Sub Exit Sub
End If End If
btnSave.Enabled = False btnSave.Enabled = False
' ========== ENDE FIX 1 ==========
' ========== FIX 2: Overlay-Handle global speichern ==========
_overlayHandle = SplashScreenManager.ShowOverlayForm(Me)
_overlayActive = True
' ========== ENDE FIX 2 ==========
Try Try
If ForceGridValidation() = True Then If ForceGridValidation() = True Then
Finish_WFStep() ShowOverlaySafe()
Try
Finish_WFStep()
Finally
CloseOverlaySafe()
End Try
End If End If
Finally Finally
' ========== FIX 3: Overlay IMMER schließen ==========
_overlayActive = False
Try
SplashScreenManager.CloseOverlayForm(_overlayHandle)
Catch ex As Exception
MyValidationLogger.Warn($"⚠️ [btnSave_Click] Overlay-Close failed: {ex.Message}")
End Try
_overlayHandle = Nothing
' ========== ENDE FIX 3 ==========
' ========== FIX 4: Button nur re-enablen wenn Form nicht schließt ==========
If Not _FormClosing AndAlso Not Me.IsDisposed Then If Not _FormClosing AndAlso Not Me.IsDisposed Then
btnSave.Enabled = True btnSave.Enabled = True
Else Else
MyValidationLogger.Debug("btnSave_Click: Form closing, Button bleibt disabled") MyValidationLogger.Debug("btnSave_Click: Form closing, Button bleibt disabled")
End If End If
' ========== ENDE FIX 4 ==========
End Try End Try
End Sub End Sub
@@ -5374,13 +5492,6 @@ Public Class frmValidator
End Function End Function
Sub Finish_WFStep(Optional includeFI As Boolean = True) Sub Finish_WFStep(Optional includeFI As Boolean = True)
Dim oHandle As Object = Nothing
Dim overlayStartedHere As Boolean = False
If Not _overlayActive Then
oHandle = SplashScreenManager.ShowOverlayForm(Me)
_overlayActive = True
overlayStartedHere = True
End If
Dim perfStart As DateTime = DateTime.MinValue Dim perfStart As DateTime = DateTime.MinValue
Dim perfLastCheck As DateTime = DateTime.MinValue Dim perfLastCheck As DateTime = DateTime.MinValue
If LOG_HOTSPOTS Then If LOG_HOTSPOTS Then
@@ -5392,6 +5503,7 @@ Public Class frmValidator
MyValidationLogger.Debug("Abschluss für DocID " & CURRENT_DOC_ID & " wird gestartet ...") MyValidationLogger.Debug("Abschluss für DocID " & CURRENT_DOC_ID & " wird gestartet ...")
Dim oErrorOcurred As Boolean = False Dim oErrorOcurred As Boolean = False
If OverrideAll = False Then If OverrideAll = False Then
If Check_UpdateIndexe() = True Then If Check_UpdateIndexe() = True Then
If LOG_HOTSPOTS Then If LOG_HOTSPOTS Then
MyValidationLogger.Info($"[PERF] Finish_WFStep nach Check_UpdateIndexe: {(DateTime.Now - perfLastCheck).TotalMilliseconds}ms") MyValidationLogger.Info($"[PERF] Finish_WFStep nach Check_UpdateIndexe: {(DateTime.Now - perfLastCheck).TotalMilliseconds}ms")
@@ -5399,10 +5511,7 @@ Public Class frmValidator
End If End If
If PROFIL_FINISH_SQL <> String.Empty Then If PROFIL_FINISH_SQL <> String.Empty Then
If btnFinish_continue() = False Then If btnFinish_continue() = False Then
If overlayStartedHere Then CloseOverlaySafe()
_overlayActive = False
SplashScreenManager.CloseOverlayForm(oHandle)
End If
Exit Sub Exit Sub
End If End If
End If End If
@@ -5544,6 +5653,8 @@ Public Class frmValidator
My.Settings.Save() My.Settings.Save()
frmError.ShowDialog() frmError.ShowDialog()
oErrorOcurred = True oErrorOcurred = True
Else
End If End If
End If End If
If oErrorOcurred = True Then If oErrorOcurred = True Then
@@ -5562,7 +5673,9 @@ Public Class frmValidator
End If End If
Try Try
If Override = True And Override_SQLCommand <> "" Then If Override = True And Override_SQLCommand <> "" Then
DatabaseFallback.ExecuteNonQueryECM(Override_SQLCommand) DatabaseFallback.ExecuteNonQueryECM(Override_SQLCommand)
End If End If
If LOG_HOTSPOTS Then If LOG_HOTSPOTS Then
MyValidationLogger.Info($"[PERF] Finish_WFStep nach Override-SQL: {(DateTime.Now - perfLastCheck).TotalMilliseconds}ms") MyValidationLogger.Info($"[PERF] Finish_WFStep nach Override-SQL: {(DateTime.Now - perfLastCheck).TotalMilliseconds}ms")
@@ -5728,10 +5841,6 @@ Public Class frmValidator
frmError.ShowDialog() frmError.ShowDialog()
oErrorOcurred = True oErrorOcurred = True
MyValidationLogger.Info("Unexpected error in Finish: " & ex.Message, True) MyValidationLogger.Info("Unexpected error in Finish: " & ex.Message, True)
If overlayStartedHere Then
_overlayActive = False
SplashScreenManager.CloseOverlayForm(oHandle)
End If
Exit Sub Exit Sub
End Try End Try
Else Else
@@ -5739,17 +5848,6 @@ Public Class frmValidator
MyValidationLogger.Warn($"⚠️ [Finish_WFStep] Validierung fehlgeschlagen → OpenfrmError") MyValidationLogger.Warn($"⚠️ [Finish_WFStep] Validierung fehlgeschlagen → OpenfrmError")
OpenfrmError(oErrMsgMissingInput) ' ← Statt: frmError.ShowDialog() OpenfrmError(oErrMsgMissingInput) ' ← Statt: frmError.ShowDialog()
oErrorOcurred = True oErrorOcurred = True
' ========== FIX: Overlay schließen NACH Dialog ==========
If overlayStartedHere Then
_overlayActive = False
Try
SplashScreenManager.CloseOverlayForm(_overlayHandle)
Catch ex As Exception
MyValidationLogger.Warn($"⚠️ [Finish_WFStep] Overlay-Close failed: {ex.Message}")
End Try
_overlayHandle = Nothing
End If
' ========== ENDE FIX ==========
Exit Sub Exit Sub
End If End If
Else Else
@@ -5764,7 +5862,7 @@ Public Class frmValidator
perfLastCheck = DateTime.Now perfLastCheck = DateTime.Now
End If End If
OverrideAll = False OverrideAll = False
' Overlay wird weiter unten geschlossen (vor Load_Next_Document bzw. BeginInvoke)
End If End If
If oErrorOcurred = True Then If oErrorOcurred = True Then
@@ -5782,13 +5880,11 @@ Public Class frmValidator
End If End If
End If End If
If CURRENT_JUMP_DOC_GUID <> 0 Then If CURRENT_JUMP_DOC_GUID <> 0 Then
CURRENT_DOC_GUID = 0 CURRENT_DOC_GUID = 0
MyValidationLogger.Info($"[Finish_WFStep] CURRENT_JUMP_DOC_GUID <> 0 → verzögertes Close()") MyValidationLogger.Info($"[Finish_WFStep] CURRENT_JUMP_DOC_GUID <> 0 → verzögertes Close()")
If overlayStartedHere Then CloseOverlaySafe()
_overlayActive = False
SplashScreenManager.CloseOverlayForm(oHandle)
End If
BeginInvoke(New Action(Sub() BeginInvoke(New Action(Sub()
If Not Me.IsDisposed Then If Not Me.IsDisposed Then
MyValidationLogger.Debug("[BeginInvoke] Führe Me.Close() aus") MyValidationLogger.Debug("[BeginInvoke] Führe Me.Close() aus")
@@ -5801,27 +5897,12 @@ Public Class frmValidator
Else Else
Load_Next_Document(False) Load_Next_Document(False)
If overlayStartedHere Then
_overlayActive = False
SplashScreenManager.CloseOverlayForm(oHandle)
End If
If LOG_HOTSPOTS Then If LOG_HOTSPOTS Then
MyValidationLogger.Info($"[PERF] Finish_WFStep nach Load_Next_Document: {(DateTime.Now - perfLastCheck).TotalMilliseconds}ms") MyValidationLogger.Info($"[PERF] Finish_WFStep nach Load_Next_Document: {(DateTime.Now - perfLastCheck).TotalMilliseconds}ms")
perfLastCheck = DateTime.Now perfLastCheck = DateTime.Now
End If End If
Focus_FirstControl() Focus_FirstControl()
End If End If
' ========== FIX: Overlay schließen am Ende ==========
If overlayStartedHere Then
_overlayActive = False
Try
SplashScreenManager.CloseOverlayForm(_overlayHandle)
Catch ex As Exception
MyValidationLogger.Warn($"⚠️ [Finish_WFStep] Overlay-Close failed: {ex.Message}")
End Try
_overlayHandle = Nothing
End If
' ========== ENDE FIX ==========
If LOG_HOTSPOTS Then If LOG_HOTSPOTS Then
MyValidationLogger.Info($"[PERF] Finish_WFStep GESAMT: {(DateTime.Now - perfStart).TotalMilliseconds}ms") MyValidationLogger.Info($"[PERF] Finish_WFStep GESAMT: {(DateTime.Now - perfStart).TotalMilliseconds}ms")
End If End If
@@ -6842,11 +6923,7 @@ Public Class frmValidator
Return Return
End If End If
_isShowingErrorDialog = True _isShowingErrorDialog = True
' ========== ENDE FIX ========== CloseOverlaySafe()
' ========== KRITISCH: Overlay NICHT hier schließen! ==========
' Das macht der Aufrufer (Finish_WFStep oder btnSave_Click)!
' ========== ENDE KRITISCH ==========
' 2. Events blockieren ' 2. Events blockieren
_suppressLookupEvents = True _suppressLookupEvents = True
@@ -7120,7 +7197,8 @@ Public Class frmValidator
End Sub End Sub
Sub Datei_ueberspringen() Sub Datei_ueberspringen()
Dim oHandle = SplashScreenManager.ShowOverlayForm(Me) ShowOverlaySafe()
Dim perfStart As DateTime = If(LOG_HOTSPOTS, DateTime.Now, Nothing) Dim perfStart As DateTime = If(LOG_HOTSPOTS, DateTime.Now, Nothing)
Dim perfLastCheck As DateTime = perfStart Dim perfLastCheck As DateTime = perfStart
If LOG_HOTSPOTS Then If LOG_HOTSPOTS Then
@@ -7183,7 +7261,7 @@ Public Class frmValidator
MyValidationLogger.Info($" frmValidator.IsDisposed: {Me.IsDisposed}") MyValidationLogger.Info($" frmValidator.IsDisposed: {Me.IsDisposed}")
' ========== ENDE DIAGNOSE ========== ' ========== ENDE DIAGNOSE ==========
End If End If
SplashScreenManager.CloseOverlayForm(oHandle) CloseOverlaySafe()
End Try End Try
End Sub End Sub
@@ -7413,7 +7491,7 @@ Public Class frmValidator
Private Sub bbtniRefresh_ItemClick(sender As Object, e As ItemClickEventArgs) Handles bbtniRefresh.ItemClick Private Sub bbtniRefresh_ItemClick(sender As Object, e As ItemClickEventArgs) Handles bbtniRefresh.ItemClick
' ========== KRITISCH: Events KOMPLETT blockieren während Refresh ========== ' ========== KRITISCH: Events KOMPLETT blockieren während Refresh ==========
_suppressLookupEvents = True _suppressLookupEvents = True
Dim oHandle = SplashScreenManager.ShowOverlayForm(Me) ShowOverlaySafe()
Try Try
Reload_Controls("") Reload_Controls("")
@@ -7424,8 +7502,8 @@ Public Class frmValidator
listChangedLookup.Clear() listChangedLookup.Clear()
SetStatusLabel("All Data refreshed", "Yellow") SetStatusLabel("All Data refreshed", "Yellow")
Finally Finally
_suppressLookupEvents = False ' ← Erst NACH allem wieder freigeben _suppressLookupEvents = False '
SplashScreenManager.CloseOverlayForm(oHandle) CloseOverlaySafe()
End Try End Try
End Sub End Sub
@@ -7520,15 +7598,12 @@ Public Class frmValidator
End Sub End Sub
Private Sub BbtnItm_ItemClick(sender As Object, e As ItemClickEventArgs) Handles BbtnitmSave.ItemClick Private Sub BbtnItm_ItemClick(sender As Object, e As ItemClickEventArgs) Handles BbtnitmSave.ItemClick
' ========== FIX 1: Button-State-Management ==========
If BbtnitmSave.Enabled = False Then If BbtnitmSave.Enabled = False Then
MyValidationLogger.Warn("BbtnitmSave_ItemClick: Button bereits disabled, Exit Sub") MyValidationLogger.Warn("BbtnitmSave_ItemClick: Button bereits disabled, Exit Sub")
Exit Sub Exit Sub
End If End If
BbtnitmSave.Enabled = False BbtnitmSave.Enabled = False
' ========== ENDE FIX 1 ========== ShowOverlaySafe() ' ✅ Overlay hier öffnen
Dim oHandle = SplashScreenManager.ShowOverlayForm(Me)
Try Try
' ========== FIX 2: Nur EINEN Check-Aufruf ========== ' ========== FIX 2: Nur EINEN Check-Aufruf ==========
If Check_UpdateIndexe() = True Then If Check_UpdateIndexe() = True Then
@@ -7545,16 +7620,15 @@ Public Class frmValidator
MsgBox("Unexpeceted error while savign data! Please check Your log and try again.", MsgBoxStyle.Critical) MsgBox("Unexpeceted error while savign data! Please check Your log and try again.", MsgBoxStyle.Critical)
End If End If
' ========== ENDE FIX 2 ==========
Finally Finally
' ========== FIX 3: Button nur re-enablen wenn Form nicht schließt ========== CloseOverlaySafe()
If Not _FormClosing AndAlso Not Me.IsDisposed Then If Not _FormClosing AndAlso Not Me.IsDisposed Then
BbtnitmSave.Enabled = True BbtnitmSave.Enabled = True
Else Else
MyValidationLogger.Debug("BbtnitmSave_ItemClick: Form closing, Button bleibt disabled") MyValidationLogger.Debug("BbtnitmSave_ItemClick: Form closing, Button bleibt disabled")
End If End If
SplashScreenManager.CloseOverlayForm(oHandle)
' ========== ENDE FIX 3 ==========
End Try End Try
End Sub End Sub
Private Sub SaveDevExpressGridControl_Layout(pProfilID As Integer, pControlID As Integer, pGridView As DevExpress.XtraGrid.Views.Grid.GridView) Private Sub SaveDevExpressGridControl_Layout(pProfilID As Integer, pControlID As Integer, pGridView As DevExpress.XtraGrid.Views.Grid.GridView)