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 GridColumns As New Dictionary(Of Integer, DataTable)
''' <summary>
''' Standard Eigenschaften für alle Controls
''' </summary>
@@ -533,12 +535,11 @@ Public Class ClassControlCreator
End Function
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 oControlId = DirectCast(oControl.Tag, ControlMetadata).Guid
Dim oView As GridView
Dim oControlName = oControl.Name
oControl.ForceInitialize()
oView = oControl.MainView
@@ -635,9 +636,13 @@ Public Class ClassControlCreator
End Try
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)
' 08.11.2021: Fix editor being empty on first open
oView.FocusInvalidRow()
Return oControl

View File

@@ -28,6 +28,60 @@ Public Class ClassFormat
End Select
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>
''' Converts a string according to the type information, using the invariant culture
@@ -41,25 +95,35 @@ Public Class ClassFormat
Select Case pType
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
LOGGER.Debug($"GetConvertedValue: Converting {pValue.ToString} to Currency ")
If Double.TryParse(pValue, NumberStyles.Currency, CultureInfo.InvariantCulture, oConvertedValue) Then
Dim normalizedValue As String = NormalizeNumericString(pValue?.ToString())
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_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
If Integer.TryParse(pValue, NumberStyles.Integer, CultureInfo.InvariantCulture, oConvertedValue) Then
Return oConvertedValue
End If
Try
Dim normalizedValue As String = NormalizeNumericString(pValue?.ToString())
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
LOGGER.Debug($"GetConvertedValue - Case ELSE - pType is {pType}")
Try

View File

@@ -209,7 +209,7 @@
If IDB_USES_WMFILESTORE Then
oID_IS_FOREIGN = 1
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};"
LOGGER.Debug($"Delete_Term_Object_From_Metadata: {oDELSQL}")
'DatabaseFallback.ExecuteNonQueryIDB(oDELSQL)
@@ -322,6 +322,7 @@
Return True
Else
'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;"
LOGGER.Debug(oPRIDB_NEW_OBJ_DATA)
' Return DatabaseFallback.ExecuteNonQueryIDB(oPRIDB_NEW_OBJ_DATA)

View File

@@ -27,10 +27,12 @@ Namespace ControlCreator
Private isApplyingInheritedValue As Boolean
Private _FormulaColumnNames As New HashSet(Of String)(StringComparer.OrdinalIgnoreCase)
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
_Logger = pLogConfig.GetLogger()
_GridTables = pGridTables
_currencySymbol = pCurrencySymbol
End Sub
Public Function CreateGridColumns(pColumnTable As DataTable) As DataTable
@@ -201,15 +203,15 @@ Namespace ControlCreator
End If
End Function
' 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
' Variante A: Standard-Währungsformat aus aktueller Kultur
' oCol.SummaryItem.DisplayFormat = "SUM: {0:C2}"
' Variante B: Kulturunabhängig, Symbol explizit anhängen
oCol.SummaryItem.DisplayFormat = $"SUM: {{0:N2}} {currencySymbol}"
oCol.SummaryItem.DisplayFormat = $"SUM: {{0:N2}} {_currencySymbol}"
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
For Each oCol As GridColumn In pGridView.Columns
Dim oColumnData As DataRow = pColumnTable.
@@ -255,7 +257,8 @@ Namespace ControlCreator
Case "CURRENCY"
oCol.DisplayFormat.FormatType = FormatType.Custom
oCol.DisplayFormat.FormatString = "C2"
oCol.DisplayFormat.FormatString = $"N2 {_currencySymbol}"
End Select
Dim oSummaryFunction As String = oColumnData.Item("SUMMARY_FUNCTION")
@@ -272,7 +275,7 @@ Namespace ControlCreator
oShouldDisplayFooter = True
Case Constants.AGGREGATE_TOTAL_CURRENCY
ApplyCurrencySummaryFormat(oCol, pcurrencySymbol)
ApplyCurrencySummaryFormat(oCol)
oShouldDisplayFooter = True
Case Constants.AGGREGATE_TOTAL_AVG
@@ -307,10 +310,10 @@ Namespace ControlCreator
End With
End If
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")
oCultureInfo.NumberFormat.CurrencySymbol = pCurrency
oCultureInfo.NumberFormat.CurrencySymbol = _currencySymbol
Dim riTextEdit As RepositoryItemTextEdit = New RepositoryItemTextEdit()
riTextEdit.MaskSettings.Configure(Of MaskSettings.Numeric)(Sub(settings)
settings.MaskExpression = "c"
@@ -328,6 +331,12 @@ Namespace ControlCreator
Continue For
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
' den berechneten Wert nach RefreshRowCell überschreibt.
Dim oFormulaExpression = ObjectEx.NotNull(oColumnData.Item("FORMULA_EXPRESSION"), String.Empty)
@@ -340,7 +349,7 @@ Namespace ControlCreator
Select Case oColumnType
Case "CURRENCY"
oCol.DisplayFormat.FormatType = FormatType.Custom
' *** WICHTIG: NUR ColumnEdit setzen, KEIN DisplayFormat mehr! ***
oCol.ColumnEdit = riTextEdit
End Select
Next
@@ -380,6 +389,55 @@ Namespace ControlCreator
newRowModified = False
End Try
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)
Try
@@ -800,16 +858,7 @@ Namespace ControlCreator
Return entry
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)
Dim view As GridView = TryCast(sender, GridView)
Dim oFocusedColumn As GridColumn = view.FocusedColumn

View File

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

View File

@@ -125,7 +125,7 @@
AAEAAAD/////AQAAAAAAAAAMAgAAAFdTeXN0ZW0uV2luZG93cy5Gb3JtcywgVmVyc2lvbj00LjAuMC4w
LCBDdWx0dXJlPW5ldXRyYWwsIFB1YmxpY0tleVRva2VuPWI3N2E1YzU2MTkzNGUwODkFAQAAACZTeXN0
ZW0uV2luZG93cy5Gb3Jtcy5JbWFnZUxpc3RTdHJlYW1lcgEAAAAERGF0YQcCAgAAAAkDAAAADwMAAADw
CAAAAk1TRnQBSQFMAgEBAgEAAcgBCwHIAQsBEAEAARABAAT/AQkBAAj/AUIBTQE2AQQGAAE2AQQCAAEo
CAAAAk1TRnQBSQFMAgEBAgEAAfABCwHwAQsBEAEAARABAAT/AQkBAAj/AUIBTQE2AQQGAAE2AQQCAAEo
AwABQAMAARADAAEBAQABCAYAAQQYAAGAAgABgAMAAoABAAGAAwABgAEAAYABAAKAAgADwAEAAcAB3AHA
AQAB8AHKAaYBAAEzBQABMwEAATMBAAEzAQACMwIAAxYBAAMcAQADIgEAAykBAANVAQADTQEAA0IBAAM5
AQABgAF8Af8BAAJQAf8BAAGTAQAB1gEAAf8B7AHMAQABxgHWAe8BAAHWAucBAAGQAakBrQIAAf8BMwMA
@@ -1496,36 +1496,9 @@
<data name="RibbonControl1.Location" type="System.Drawing.Point, System.Drawing">
<value>0, 0</value>
</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">
<value>Start</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="RibbonPageTabelle.Text" xml:space="preserve">
<value>Tabelle</value>
</data>
@@ -1583,24 +1556,6 @@
<data name="&gt;&gt;GridControlWorkflows.ZOrder" xml:space="preserve">
<value>0</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>
@@ -1692,12 +1647,6 @@
<metadata name="cmsNavPane.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
<value>863, 17</value>
</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">
<value>220, 30</value>
</data>
@@ -1880,6 +1829,69 @@
<data name="&gt;&gt;Panel1.ZOrder" xml:space="preserve">
<value>2</value>
</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">
<value>986, 17</value>
</metadata>
@@ -1889,27 +1901,6 @@
<metadata name="ContextMenuNotifyIcon.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
<value>1220, 17</value>
</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">
<value>291, 100</value>
</data>
@@ -2005,6 +1996,27 @@
<data name="NotifyIcon1.Visible" type="System.Boolean, mscorlib">
<value>True</value>
</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">
<value>605, 17</value>
</metadata>
@@ -3432,6 +3444,9 @@
<data name="miView.Caption" xml:space="preserve">
<value>&amp;Ansicht</value>
</data>
<data name="miBackground.Caption" xml:space="preserve">
<value>&amp;Hintergrund</value>
</data>
<data name="miPageLayout.Caption" xml:space="preserve">
<value>&amp;Seiten Layout</value>
</data>
@@ -3444,9 +3459,6 @@
<data name="miToolbars.Caption" xml:space="preserve">
<value>Bars</value>
</data>
<data name="miBackground.Caption" xml:space="preserve">
<value>&amp;Hintergrund</value>
</data>
<data name="PrintPreviewBarCheckItem1.Caption" xml:space="preserve">
<value>PDF Dokument</value>
</data>

View File

@@ -1977,6 +1977,8 @@ Public Class frmMain
Dim useWaitCursorApplied As Boolean = False
Dim previousMessage As String = bsiMessage.Caption
Dim messageApplied As Boolean = False
Dim oHandle As Object = Nothing
Dim overlayStartedHere As Boolean = False
If LOG_HOTSPOTS Then
perfStart = DateTime.Now
@@ -1987,6 +1989,14 @@ Public Class frmMain
CURRENT_ProfilGUID = pProfilID
WM_AHWF_docPath = String.Empty
' ========== OVERLAY ANZEIGEN ==========
If Not _overlayActive Then
oHandle = SplashScreenManager.ShowOverlayForm(Me)
_overlayActive = True
overlayStartedHere = True
End If
' ========== UI-VORBEREITUNG ==========
Me.UseWaitCursor = 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)
Dim task = Decide_Load(False, True)
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 ==========
If useWaitCursorApplied Then
Me.UseWaitCursor = False

View File

@@ -135,9 +135,10 @@ Public Class frmValidator
Private _CachedControlsByGuid As Dictionary(Of Integer, Control)
Private _isUpdatingLookup As Boolean = False
Private _suppressLookupEvents As Boolean = False
Private _overlayActive As Boolean = False
Private _isShowingErrorDialog As Boolean = False ' ← NEU: Klassenvariable oben hinzufügen
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
@@ -163,7 +164,70 @@ Public Class frmValidator
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
Dim oOperationMode As OperationMode
@@ -2015,6 +2079,11 @@ Public Class frmValidator
End Try
End Sub
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 oGrid As GridControl = oView.GridControl
Dim oMeta As ClassControlCreator.ControlMetadata = oGrid.Tag
@@ -2439,7 +2508,10 @@ Public Class frmValidator
Catch ex As Exception
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
_SetControlValue_In_Action = False
End Try
@@ -2806,6 +2878,12 @@ Public Class frmValidator
End Sub
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
If oCombobox.SelectedIndex <> -1 And _Indexe_Loaded = True Then
Dim oMeta As ClassControlCreator.ControlMetadata = oCombobox.Tag
@@ -3261,34 +3339,55 @@ Public Class frmValidator
Private Function CreateWMObject() As String
MyValidationLogger.Debug($"in GetWMDocFileString...'")
Private Function CreateWMObject() As Boolean
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
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
MyValidationLogger.Debug($"in GetWMDocFileString...'")
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
Dim _err1 As Boolean = False
MyValidationLogger.Error(ex)
MyValidationLogger.Info("Unexpected error creating WMObject(1) in GetWMDocFileString: " & ex.Message)
MyValidationLogger.Info("Error Number: " & Err.Number.ToString)
errormessage = $"Could not create a WMObject(1) for [{oWMOwnPath}]!"
frmError.ShowDialog()
' ========== FIX 4: Auch hier OpenfrmError() verwenden ==========
OpenfrmError(errormessage)
Return False
' ========== ENDE FIX 4 ==========
End Try
End Function
Private Function GetDocPathWindows(_CheckStandard As Integer)
Try
@@ -3377,7 +3476,6 @@ Public Class frmValidator
Dim oMilliseconts As Double
clsPatterns.ClearControlCache() ' Cache-Invalidierung
Dim perfStart As DateTime = DateTime.MinValue
Dim perfLastCheck As DateTime = DateTime.MinValue
If LOG_HOTSPOTS Then
@@ -3676,6 +3774,7 @@ Public Class frmValidator
End If
MyValidationLogger.Debug("frmValidator: LoadNextDocument finished!")
Catch ex As Exception
MyValidationLogger.Error(ex)
errormessage = "unexpected error in Load_Next_Document:" & ex.Message
@@ -3686,7 +3785,6 @@ Public Class frmValidator
If layoutSuspended Then
PanelValidatorControl.ResumeLayout()
End If
If LOG_HOTSPOTS Then
' ========== DIAGNOSE ENDE ==========
MyValidationLogger.Info($"[INFO] Load_Next_Document ENDE")
@@ -5089,7 +5187,7 @@ Public Class frmValidator
End Sub
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 perfLastCheck As DateTime = DateTime.MinValue
If LOG_HOTSPOTS Then
@@ -5185,49 +5283,69 @@ Public Class frmValidator
End If
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
MyValidationLogger.Info($"[PERF] frmValidation_Shown GESAMT: {(DateTime.Now - perfStart).TotalMilliseconds}ms")
End If
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
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
Private Sub btnSave_Click(sender As Object, e As EventArgs) Handles btnSave.Click
' ========== FIX 1: Button-State-Management ==========
If btnSave.Enabled = False Then
MyValidationLogger.Warn("btnSave_Click: Button bereits disabled, Exit Sub")
Exit Sub
End If
btnSave.Enabled = False
' ========== ENDE FIX 1 ==========
' ========== FIX 2: Overlay-Handle global speichern ==========
_overlayHandle = SplashScreenManager.ShowOverlayForm(Me)
_overlayActive = True
' ========== ENDE FIX 2 ==========
Try
If ForceGridValidation() = True Then
Finish_WFStep()
ShowOverlaySafe()
Try
Finish_WFStep()
Finally
CloseOverlaySafe()
End Try
End If
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
btnSave.Enabled = True
Else
MyValidationLogger.Debug("btnSave_Click: Form closing, Button bleibt disabled")
End If
' ========== ENDE FIX 4 ==========
End Try
End Sub
@@ -5374,13 +5492,6 @@ Public Class frmValidator
End Function
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 perfLastCheck As DateTime = DateTime.MinValue
If LOG_HOTSPOTS Then
@@ -5392,6 +5503,7 @@ Public Class frmValidator
MyValidationLogger.Debug("Abschluss für DocID " & CURRENT_DOC_ID & " wird gestartet ...")
Dim oErrorOcurred As Boolean = False
If OverrideAll = False Then
If Check_UpdateIndexe() = True Then
If LOG_HOTSPOTS Then
MyValidationLogger.Info($"[PERF] Finish_WFStep nach Check_UpdateIndexe: {(DateTime.Now - perfLastCheck).TotalMilliseconds}ms")
@@ -5399,10 +5511,7 @@ Public Class frmValidator
End If
If PROFIL_FINISH_SQL <> String.Empty Then
If btnFinish_continue() = False Then
If overlayStartedHere Then
_overlayActive = False
SplashScreenManager.CloseOverlayForm(oHandle)
End If
CloseOverlaySafe()
Exit Sub
End If
End If
@@ -5544,6 +5653,8 @@ Public Class frmValidator
My.Settings.Save()
frmError.ShowDialog()
oErrorOcurred = True
Else
End If
End If
If oErrorOcurred = True Then
@@ -5562,7 +5673,9 @@ Public Class frmValidator
End If
Try
If Override = True And Override_SQLCommand <> "" Then
DatabaseFallback.ExecuteNonQueryECM(Override_SQLCommand)
End If
If LOG_HOTSPOTS Then
MyValidationLogger.Info($"[PERF] Finish_WFStep nach Override-SQL: {(DateTime.Now - perfLastCheck).TotalMilliseconds}ms")
@@ -5728,10 +5841,6 @@ Public Class frmValidator
frmError.ShowDialog()
oErrorOcurred = True
MyValidationLogger.Info("Unexpected error in Finish: " & ex.Message, True)
If overlayStartedHere Then
_overlayActive = False
SplashScreenManager.CloseOverlayForm(oHandle)
End If
Exit Sub
End Try
Else
@@ -5739,17 +5848,6 @@ Public Class frmValidator
MyValidationLogger.Warn($"⚠️ [Finish_WFStep] Validierung fehlgeschlagen → OpenfrmError")
OpenfrmError(oErrMsgMissingInput) ' ← Statt: frmError.ShowDialog()
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
End If
Else
@@ -5764,7 +5862,7 @@ Public Class frmValidator
perfLastCheck = DateTime.Now
End If
OverrideAll = False
' Overlay wird weiter unten geschlossen (vor Load_Next_Document bzw. BeginInvoke)
End If
If oErrorOcurred = True Then
@@ -5782,13 +5880,11 @@ Public Class frmValidator
End If
End If
If CURRENT_JUMP_DOC_GUID <> 0 Then
CURRENT_DOC_GUID = 0
MyValidationLogger.Info($"[Finish_WFStep] CURRENT_JUMP_DOC_GUID <> 0 → verzögertes Close()")
If overlayStartedHere Then
_overlayActive = False
SplashScreenManager.CloseOverlayForm(oHandle)
End If
CloseOverlaySafe()
BeginInvoke(New Action(Sub()
If Not Me.IsDisposed Then
MyValidationLogger.Debug("[BeginInvoke] Führe Me.Close() aus")
@@ -5801,27 +5897,12 @@ Public Class frmValidator
Else
Load_Next_Document(False)
If overlayStartedHere Then
_overlayActive = False
SplashScreenManager.CloseOverlayForm(oHandle)
End If
If LOG_HOTSPOTS Then
MyValidationLogger.Info($"[PERF] Finish_WFStep nach Load_Next_Document: {(DateTime.Now - perfLastCheck).TotalMilliseconds}ms")
perfLastCheck = DateTime.Now
End If
Focus_FirstControl()
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
MyValidationLogger.Info($"[PERF] Finish_WFStep GESAMT: {(DateTime.Now - perfStart).TotalMilliseconds}ms")
End If
@@ -6842,11 +6923,7 @@ Public Class frmValidator
Return
End If
_isShowingErrorDialog = True
' ========== ENDE FIX ==========
' ========== KRITISCH: Overlay NICHT hier schließen! ==========
' Das macht der Aufrufer (Finish_WFStep oder btnSave_Click)!
' ========== ENDE KRITISCH ==========
CloseOverlaySafe()
' 2. Events blockieren
_suppressLookupEvents = True
@@ -7120,7 +7197,8 @@ Public Class frmValidator
End Sub
Sub Datei_ueberspringen()
Dim oHandle = SplashScreenManager.ShowOverlayForm(Me)
ShowOverlaySafe()
Dim perfStart As DateTime = If(LOG_HOTSPOTS, DateTime.Now, Nothing)
Dim perfLastCheck As DateTime = perfStart
If LOG_HOTSPOTS Then
@@ -7183,7 +7261,7 @@ Public Class frmValidator
MyValidationLogger.Info($" frmValidator.IsDisposed: {Me.IsDisposed}")
' ========== ENDE DIAGNOSE ==========
End If
SplashScreenManager.CloseOverlayForm(oHandle)
CloseOverlaySafe()
End Try
End Sub
@@ -7413,7 +7491,7 @@ Public Class frmValidator
Private Sub bbtniRefresh_ItemClick(sender As Object, e As ItemClickEventArgs) Handles bbtniRefresh.ItemClick
' ========== KRITISCH: Events KOMPLETT blockieren während Refresh ==========
_suppressLookupEvents = True
Dim oHandle = SplashScreenManager.ShowOverlayForm(Me)
ShowOverlaySafe()
Try
Reload_Controls("")
@@ -7424,8 +7502,8 @@ Public Class frmValidator
listChangedLookup.Clear()
SetStatusLabel("All Data refreshed", "Yellow")
Finally
_suppressLookupEvents = False ' ← Erst NACH allem wieder freigeben
SplashScreenManager.CloseOverlayForm(oHandle)
_suppressLookupEvents = False '
CloseOverlaySafe()
End Try
End Sub
@@ -7520,15 +7598,12 @@ Public Class frmValidator
End Sub
Private Sub BbtnItm_ItemClick(sender As Object, e As ItemClickEventArgs) Handles BbtnitmSave.ItemClick
' ========== FIX 1: Button-State-Management ==========
If BbtnitmSave.Enabled = False Then
MyValidationLogger.Warn("BbtnitmSave_ItemClick: Button bereits disabled, Exit Sub")
Exit Sub
End If
BbtnitmSave.Enabled = False
' ========== ENDE FIX 1 ==========
Dim oHandle = SplashScreenManager.ShowOverlayForm(Me)
ShowOverlaySafe() ' ✅ Overlay hier öffnen
Try
' ========== FIX 2: Nur EINEN Check-Aufruf ==========
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)
End If
' ========== ENDE FIX 2 ==========
Finally
' ========== FIX 3: Button nur re-enablen wenn Form nicht schließt ==========
CloseOverlaySafe()
If Not _FormClosing AndAlso Not Me.IsDisposed Then
BbtnitmSave.Enabled = True
Else
MyValidationLogger.Debug("BbtnitmSave_ItemClick: Form closing, Button bleibt disabled")
End If
SplashScreenManager.CloseOverlayForm(oHandle)
' ========== ENDE FIX 3 ==========
End Try
End Sub
Private Sub SaveDevExpressGridControl_Layout(pProfilID As Integer, pControlID As Integer, pGridView As DevExpress.XtraGrid.Views.Grid.GridView)