Aktualisierung, Speichern und Leeren von GridControl-Zellen
This commit is contained in:
@@ -33,6 +33,7 @@ Namespace ControlCreator
|
|||||||
Private Shared _ResolvedSqlCache As New Dictionary(Of String, String)
|
Private Shared _ResolvedSqlCache As New Dictionary(Of String, String)
|
||||||
|
|
||||||
Private _isRefreshingFormula As Boolean = False ' *** NEU: Flag für Formel-Refresh ***
|
Private _isRefreshingFormula As Boolean = False ' *** NEU: Flag für Formel-Refresh ***
|
||||||
|
Private _clearOperationsInProgress As New HashSet(Of String) ' Format: "GridViewHashCode|ColumnName"
|
||||||
Private _currencySymbol As String = "€"
|
Private _currencySymbol As String = "€"
|
||||||
''' <summary>
|
''' <summary>
|
||||||
''' SHARED Dictionary: Speichert das aktuelle Währungssymbol PRO GridView (via Name).
|
''' SHARED Dictionary: Speichert das aktuelle Währungssymbol PRO GridView (via Name).
|
||||||
@@ -90,70 +91,34 @@ Namespace ControlCreator
|
|||||||
For Each match As Match In matches
|
For Each match As Match In matches
|
||||||
Dim colName = match.Groups(1).Value
|
Dim colName = match.Groups(1).Value
|
||||||
Dim cellValue = pView.GetRowCellValue(rowHandle, colName)
|
Dim cellValue = pView.GetRowCellValue(rowHandle, colName)
|
||||||
Dim safeValue As String = ConvertToSqlValue(cellValue) ' Hilfsfunktion
|
Dim safeValue As String = ConvertToSqlValue(cellValue)
|
||||||
resolvedSql = resolvedSql.Replace(match.Value, safeValue)
|
resolvedSql = resolvedSql.Replace(match.Value, safeValue)
|
||||||
Next
|
Next
|
||||||
|
|
||||||
' *** SCHRITT 2: {#CTRL#...} via clsPatterns - MIT CACHE ***
|
|
||||||
' *** SCHRITT 2: {#CTRL#...} via clsPatterns - MIT CACHE ***
|
' *** SCHRITT 2: {#CTRL#...} via clsPatterns - MIT CACHE ***
|
||||||
If _ParentControl IsNot Nothing AndAlso resolvedSql.Contains("{#CTRL#") Then
|
If _ParentControl IsNot Nothing AndAlso resolvedSql.Contains("{#CTRL#") Then
|
||||||
' Cache-Key: Hash aus SQL + Control-Werten
|
' *** FIX: Cache-Key ERST NACH ReplaceAllValues erstellen! ***
|
||||||
Dim cacheKey = GenerateCacheKey(resolvedSql, _ParentControl)
|
Dim beforeReplace = resolvedSql
|
||||||
|
resolvedSql = clsPatterns.ReplaceAllValues(resolvedSql, _ParentControl, True)
|
||||||
|
|
||||||
|
' *** JETZT Cache-Key erstellen (mit aufgelösten Control-Werten) ***
|
||||||
|
Dim cacheKey = resolvedSql.GetHashCode().ToString()
|
||||||
|
|
||||||
SyncLock _ResolvedSqlCache
|
SyncLock _ResolvedSqlCache
|
||||||
If _ResolvedSqlCache.ContainsKey(cacheKey) Then
|
' Cache speichern (für nächsten Aufruf)
|
||||||
' ✅ CACHE HIT: Kein Logging → spart 380+ Log-Zeilen
|
If Not _ResolvedSqlCache.ContainsKey(cacheKey) Then
|
||||||
resolvedSql = _ResolvedSqlCache(cacheKey)
|
|
||||||
Else
|
|
||||||
' ❌ CACHE MISS: Nur HIER Debug-Logs
|
|
||||||
_Logger.Debug("[ResolveSqlTemplate] ReplaceAllValues-Cache MISS")
|
|
||||||
|
|
||||||
' *** DEBUG: Log Parent-Control (NUR beim ersten Aufruf) ***
|
|
||||||
If LOG_HOTSPOTS Then
|
|
||||||
_Logger.Debug("[ResolveSqlTemplate] _ParentControl is [{0}], has {1} controls",
|
|
||||||
_ParentControl.GetType().Name, _ParentControl.Controls.Count)
|
|
||||||
|
|
||||||
' *** ERWEITERTE SUCHE: Alle Controls durchsuchen ***
|
|
||||||
Dim testLU As Control = Nothing
|
|
||||||
For Each ctrl As Control In _ParentControl.Controls
|
|
||||||
If ctrl.Name = "LU_LieferantenNummer" Then
|
|
||||||
testLU = ctrl
|
|
||||||
Exit For
|
|
||||||
End If
|
|
||||||
' Rekursiv in Child-Controls suchen
|
|
||||||
If ctrl.HasChildren Then
|
|
||||||
testLU = FindControlRecursive(ctrl, "LU_LieferantenNummer")
|
|
||||||
If testLU IsNot Nothing Then Exit For
|
|
||||||
End If
|
|
||||||
Next
|
|
||||||
|
|
||||||
If testLU IsNot Nothing AndAlso TypeOf testLU Is LookupControl3 Then
|
|
||||||
Dim luValue = DirectCast(testLU, LookupControl3).EditValue
|
|
||||||
_Logger.Debug("[ResolveSqlTemplate] LU_LieferantenNummer.EditValue = [{0}]", luValue)
|
|
||||||
Else
|
|
||||||
_Logger.Warn("[ResolveSqlTemplate] LU_LieferantenNummer NOT FOUND in _ParentControl!")
|
|
||||||
' *** LISTE ALLE CONTROLS AUF (nur beim ersten Fehler) ***
|
|
||||||
_Logger.Debug("[ResolveSqlTemplate] Available controls in _ParentControl:")
|
|
||||||
For Each ctrl In _ParentControl.Controls
|
|
||||||
_Logger.Debug(" - {0} (Type: {1})", ctrl.Name, ctrl.GetType().Name)
|
|
||||||
Next
|
|
||||||
End If
|
|
||||||
End If
|
|
||||||
|
|
||||||
' Nur bei Cache-Miss ReplaceAllValues aufrufen
|
|
||||||
Dim beforeReplace = resolvedSql
|
|
||||||
resolvedSql = clsPatterns.ReplaceAllValues(resolvedSql, _ParentControl, True)
|
|
||||||
_ResolvedSqlCache(cacheKey) = resolvedSql
|
_ResolvedSqlCache(cacheKey) = resolvedSql
|
||||||
|
_Logger.Debug("[ResolveSqlTemplate] ✓ Cached SQL: Key=[{0}]", cacheKey)
|
||||||
' *** DEBUG: Log VOR/NACH (nur bei MISS) ***
|
|
||||||
If LOG_HOTSPOTS Then
|
|
||||||
_Logger.Info("[ResolveSqlTemplate] BEFORE: {0}",
|
|
||||||
beforeReplace.Substring(0, Math.Min(150, beforeReplace.Length)))
|
|
||||||
_Logger.Info("[ResolveSqlTemplate] AFTER: {0}",
|
|
||||||
resolvedSql.Substring(0, Math.Min(150, resolvedSql.Length)))
|
|
||||||
End If
|
|
||||||
End If
|
End If
|
||||||
End SyncLock
|
End SyncLock
|
||||||
|
|
||||||
|
' *** DEBUG: Log VOR/NACH (nur beim ersten Aufruf) ***
|
||||||
|
If LOG_HOTSPOTS Then
|
||||||
|
_Logger.Info("[ResolveSqlTemplate] BEFORE: {0}",
|
||||||
|
beforeReplace.Substring(0, Math.Min(150, beforeReplace.Length)))
|
||||||
|
_Logger.Info("[ResolveSqlTemplate] AFTER: {0}",
|
||||||
|
resolvedSql.Substring(0, Math.Min(150, resolvedSql.Length)))
|
||||||
|
End If
|
||||||
Else
|
Else
|
||||||
If _ParentControl Is Nothing Then
|
If _ParentControl Is Nothing Then
|
||||||
_Logger.Warn("[ResolveSqlTemplate] _ParentControl is NOTHING! Cannot replace {{#CTRL#...}}")
|
_Logger.Warn("[ResolveSqlTemplate] _ParentControl is NOTHING! Cannot replace {{#CTRL#...}}")
|
||||||
@@ -853,7 +818,7 @@ Namespace ControlCreator
|
|||||||
AddHandler pGridView.CustomRowCellEdit,
|
AddHandler pGridView.CustomRowCellEdit,
|
||||||
Sub(sender As Object, e As CustomRowCellEditEventArgs)
|
Sub(sender As Object, e As CustomRowCellEditEventArgs)
|
||||||
Try
|
Try
|
||||||
' *** NEU: Dynamische Editoren aus Cache oder neu erstellen ***
|
' *** SCHRITT 1: Dynamische Editoren ZUERST prüfen ***
|
||||||
If _DynamicEditorColumns.Contains(e.Column.FieldName) Then
|
If _DynamicEditorColumns.Contains(e.Column.FieldName) Then
|
||||||
Dim oColumnData As DataRow = pColumnTable.
|
Dim oColumnData As DataRow = pColumnTable.
|
||||||
Select($"SPALTENNAME = '{e.Column.FieldName}'").
|
Select($"SPALTENNAME = '{e.Column.FieldName}'").
|
||||||
@@ -864,38 +829,52 @@ Namespace ControlCreator
|
|||||||
Dim oConnectionId As Integer = oColumnData.ItemEx("CONNECTION_ID", 1)
|
Dim oConnectionId As Integer = oColumnData.ItemEx("CONNECTION_ID", 1)
|
||||||
Dim oIsAdvancedLookup As Boolean = oColumnData.ItemEx("ADVANCED_LOOKUP", False)
|
Dim oIsAdvancedLookup As Boolean = oColumnData.ItemEx("ADVANCED_LOOKUP", False)
|
||||||
|
|
||||||
' *** SQL auflösen (für Cache-Key) ***
|
If String.IsNullOrEmpty(oSqlCommand) Then
|
||||||
Dim resolvedSql = ResolveSqlTemplate(oSqlCommand, TryCast(sender, GridView), e.RowHandle)
|
_Logger.Warn("⚠️ [CustomRowCellEdit] Column [{0}] has no SQL_COMMAND!", e.Column.FieldName)
|
||||||
|
Return
|
||||||
|
End If
|
||||||
|
|
||||||
' *** CACHE-KEY: Spaltenname + aufgelöstes SQL (HashCode) ***
|
' *** NEU: ResolveSqlTemplate HIER aufrufen! ***
|
||||||
|
Dim resolvedSql As String = ResolveSqlTemplate(oSqlCommand, DirectCast(sender, GridView), e.RowHandle)
|
||||||
|
|
||||||
|
' Cache-Key basiert auf RESOLVED SQL
|
||||||
Dim cacheKey As String = $"{e.Column.FieldName}|{resolvedSql.GetHashCode()}"
|
Dim cacheKey As String = $"{e.Column.FieldName}|{resolvedSql.GetHashCode()}"
|
||||||
|
|
||||||
' *** CACHE-CHECK ***
|
' Cache prüfen
|
||||||
SyncLock _DynamicEditorCacheShared
|
SyncLock _DynamicEditorCacheShared
|
||||||
If _DynamicEditorCacheShared.ContainsKey(cacheKey) Then
|
If _DynamicEditorCacheShared.ContainsKey(cacheKey) Then
|
||||||
' ✅ CACHE HIT: Editor wiederverwenden
|
_Logger.Info("[CustomRowCellEdit] ✓ CACHE HIT: [{0}]", cacheKey)
|
||||||
e.RepositoryItem = _DynamicEditorCacheShared(cacheKey)
|
e.RepositoryItem = _DynamicEditorCacheShared(cacheKey)
|
||||||
Else
|
Return
|
||||||
' ❌ CACHE MISS: Neuen Editor erstellen
|
|
||||||
_Logger.Info("[CustomRowCellEdit] 🆕 MISS: Creating editor for [{0}]", e.Column.FieldName)
|
|
||||||
|
|
||||||
Dim realEditor = CreateRowSpecificEditor(e.Column.FieldName, resolvedSql, oConnectionId, oIsAdvancedLookup)
|
|
||||||
|
|
||||||
If realEditor IsNot Nothing Then
|
|
||||||
' *** IN CACHE SPEICHERN ***
|
|
||||||
_DynamicEditorCacheShared(cacheKey) = realEditor
|
|
||||||
e.RepositoryItem = realEditor
|
|
||||||
_Logger.Info("[CustomRowCellEdit] ✓ Cached [{0}] editor (Type=[{1}])", e.Column.FieldName, realEditor.GetType().Name)
|
|
||||||
Else
|
|
||||||
_Logger.Warn("[CustomRowCellEdit] CreateRowSpecificEditor returned Nothing for [{0}]", e.Column.FieldName)
|
|
||||||
End If
|
|
||||||
End If
|
End If
|
||||||
End SyncLock
|
End SyncLock
|
||||||
|
|
||||||
|
' Editor erstellen mit RESOLVED SQL
|
||||||
|
_Logger.Info("[CustomRowCellEdit] 🆕 MISS: Creating editor for [{0}]", e.Column.FieldName)
|
||||||
|
Dim realEditor = CreateRowSpecificEditor(
|
||||||
|
e.Column.FieldName,
|
||||||
|
resolvedSql,
|
||||||
|
oConnectionId,
|
||||||
|
oIsAdvancedLookup,
|
||||||
|
DirectCast(sender, GridView),
|
||||||
|
e.RowHandle
|
||||||
|
)
|
||||||
|
If realEditor IsNot Nothing Then
|
||||||
|
SyncLock _DynamicEditorCacheShared
|
||||||
|
If Not _DynamicEditorCacheShared.ContainsKey(cacheKey) Then
|
||||||
|
_DynamicEditorCacheShared.Add(cacheKey, realEditor)
|
||||||
|
End If
|
||||||
|
End SyncLock
|
||||||
|
_Logger.Info("[CustomRowCellEdit] ✓ Cached [{0}] editor (Type=[{1}])", e.Column.FieldName, realEditor.GetType().Name)
|
||||||
|
e.RepositoryItem = realEditor
|
||||||
|
Else
|
||||||
|
_Logger.Warn("[CustomRowCellEdit] CreateRowSpecificEditor returned Nothing for [{0}]", e.Column.FieldName)
|
||||||
|
End If
|
||||||
End If
|
End If
|
||||||
Return
|
Return ' ✅ WICHTIG: Verlässt Handler nach dynamischem Editor!
|
||||||
End If
|
End If
|
||||||
|
|
||||||
' Standard-Editor aus Cache
|
' *** SCHRITT 2: Statische Editoren (nur wenn NICHT dynamisch) ***
|
||||||
Dim oEditorExists = GridTables_TestEditorExistsByControlAndColumn(pControlId, e.Column.FieldName)
|
Dim oEditorExists = GridTables_TestEditorExistsByControlAndColumn(pControlId, e.Column.FieldName)
|
||||||
If oEditorExists Then
|
If oEditorExists Then
|
||||||
_Logger.Debug("[CustomRowCellEdit] Assigning RepositoryItem for column [{0}] from GridTables cache.", e.Column.FieldName)
|
_Logger.Debug("[CustomRowCellEdit] Assigning RepositoryItem for column [{0}] from GridTables cache.", e.Column.FieldName)
|
||||||
@@ -1065,6 +1044,91 @@ Namespace ControlCreator
|
|||||||
End If
|
End If
|
||||||
End Sub
|
End Sub
|
||||||
|
|
||||||
|
AddHandler pGridView.ShownEditor,
|
||||||
|
Sub(sender As Object, e As EventArgs)
|
||||||
|
Try
|
||||||
|
Dim view As GridView = TryCast(sender, GridView)
|
||||||
|
If view Is Nothing OrElse view.ActiveEditor Is Nothing Then Return
|
||||||
|
|
||||||
|
' Nur für LookupControl3
|
||||||
|
Dim activeEditor = TryCast(view.ActiveEditor, LookupControl3)
|
||||||
|
If activeEditor Is Nothing Then Return
|
||||||
|
|
||||||
|
' Nur für dynamische Editoren
|
||||||
|
Dim columnName = view.FocusedColumn?.FieldName
|
||||||
|
If String.IsNullOrEmpty(columnName) OrElse Not _DynamicEditorColumns.Contains(columnName) Then Return
|
||||||
|
|
||||||
|
' Verhindere doppelte Registrierung via Tag
|
||||||
|
If activeEditor.Tag IsNot Nothing AndAlso activeEditor.Tag.ToString() = "ClearHandlerRegistered" Then
|
||||||
|
_Logger.Debug("[ShownEditor] Properties.SelectedValuesChanged-Handler bereits registriert für [{0}]", columnName)
|
||||||
|
Return
|
||||||
|
End If
|
||||||
|
|
||||||
|
_Logger.Debug("[ShownEditor] ✓ Registriere Properties.SelectedValuesChanged-Handler für [{0}]", columnName)
|
||||||
|
|
||||||
|
' *** Properties.SelectedValuesChanged mit GLOBALEM Guard ***
|
||||||
|
Dim clearHandler As RepositoryItemLookupControl3.SelectedValuesChangedHandler =
|
||||||
|
Sub(editorSender As Object, selectedValues As List(Of String))
|
||||||
|
Try
|
||||||
|
Dim isCleared As Boolean = selectedValues Is Nothing OrElse selectedValues.Count = 0
|
||||||
|
|
||||||
|
If isCleared Then
|
||||||
|
' *** GLOBALES GUARD: Key aus GridView-Hash + ColumnName ***
|
||||||
|
Dim guardKey As String = $"{view.GetHashCode()}|{columnName}"
|
||||||
|
|
||||||
|
SyncLock _clearOperationsInProgress
|
||||||
|
If _clearOperationsInProgress.Contains(guardKey) Then
|
||||||
|
_Logger.Debug("[LookupControl3] Clear already in progress for [{0}] → SKIP", columnName)
|
||||||
|
Return
|
||||||
|
End If
|
||||||
|
|
||||||
|
' Guard aktivieren
|
||||||
|
_clearOperationsInProgress.Add(guardKey)
|
||||||
|
End SyncLock
|
||||||
|
|
||||||
|
_Logger.Info("[LookupControl3] Properties.SelectedValuesChanged leer → clearing [{0}]", columnName)
|
||||||
|
|
||||||
|
' BeginInvoke: Lookup ERST schließen lassen, DANN Zelle leeren
|
||||||
|
view.GridControl.BeginInvoke(New Action(
|
||||||
|
Sub()
|
||||||
|
Try
|
||||||
|
Dim rowHandle = view.FocusedRowHandle
|
||||||
|
If view.IsValidRowHandle(rowHandle) Then
|
||||||
|
view.SetRowCellValue(rowHandle, columnName, String.Empty)
|
||||||
|
_Logger.Debug("[LookupControl3] ✓ Cell cleared: Row={0}, Column={1}", rowHandle, columnName)
|
||||||
|
End If
|
||||||
|
Catch ex As Exception
|
||||||
|
_Logger.Error("[LookupControl3] Error in BeginInvoke: {0}", ex.Message)
|
||||||
|
_Logger.Error(ex)
|
||||||
|
Finally
|
||||||
|
' *** GUARD ZURÜCKSETZEN (nach UI-Update) ***
|
||||||
|
SyncLock _clearOperationsInProgress
|
||||||
|
_clearOperationsInProgress.Remove(guardKey)
|
||||||
|
End SyncLock
|
||||||
|
End Try
|
||||||
|
End Sub))
|
||||||
|
Else
|
||||||
|
_Logger.Debug("[LookupControl3] Properties.SelectedValuesChanged.Count=[{0}] → keine Löschung", selectedValues.Count)
|
||||||
|
End If
|
||||||
|
|
||||||
|
Catch ex As Exception
|
||||||
|
_Logger.Error("[LookupControl3] Properties.SelectedValuesChanged Error: {0}", ex.Message)
|
||||||
|
_Logger.Error(ex)
|
||||||
|
End Try
|
||||||
|
End Sub
|
||||||
|
|
||||||
|
' Handler registrieren
|
||||||
|
AddHandler activeEditor.Properties.SelectedValuesChanged, clearHandler
|
||||||
|
|
||||||
|
' Markierung setzen (verhindert doppelte Registrierung)
|
||||||
|
activeEditor.Tag = "ClearHandlerRegistered"
|
||||||
|
|
||||||
|
Catch ex As Exception
|
||||||
|
_Logger.Error("[ShownEditor] Properties.SelectedValuesChanged-Handler Error: {0}", ex.Message)
|
||||||
|
_Logger.Error(ex)
|
||||||
|
End Try
|
||||||
|
End Sub
|
||||||
|
|
||||||
AddHandler pGridView.ValidateRow, AddressOf View_ValidateRow
|
AddHandler pGridView.ValidateRow, AddressOf View_ValidateRow
|
||||||
AddHandler pControl.LostFocus, AddressOf Control_LostFocus
|
AddHandler pControl.LostFocus, AddressOf Control_LostFocus
|
||||||
|
|
||||||
@@ -1398,10 +1462,13 @@ CheckNewItemRow:
|
|||||||
''' Wird verwendet, wenn SQL_COMMAND Platzhalter wie {#TBCOL#...} enthält.
|
''' Wird verwendet, wenn SQL_COMMAND Platzhalter wie {#TBCOL#...} enthält.
|
||||||
''' </summary>
|
''' </summary>
|
||||||
Private Function CreateRowSpecificEditor(
|
Private Function CreateRowSpecificEditor(
|
||||||
columnName As String,
|
columnName As String,
|
||||||
resolvedSql As String,
|
resolvedSql As String,
|
||||||
connectionId As Integer,
|
connectionId As Integer,
|
||||||
isAdvancedLookup As Boolean) As RepositoryItem
|
isAdvancedLookup As Boolean,
|
||||||
|
pView As GridView, ' ← NEU!
|
||||||
|
pRowHandle As Integer ' ← NEU!
|
||||||
|
) As RepositoryItem
|
||||||
|
|
||||||
Try
|
Try
|
||||||
If LOG_HOTSPOTS Then _Logger.Debug("[CreateRowSpecificEditor] Executing SQL for column [{0}]: {1}", columnName, resolvedSql)
|
If LOG_HOTSPOTS Then _Logger.Debug("[CreateRowSpecificEditor] Executing SQL for column [{0}]: {1}", columnName, resolvedSql)
|
||||||
@@ -1418,22 +1485,17 @@ CheckNewItemRow:
|
|||||||
Return Nothing
|
Return Nothing
|
||||||
End If
|
End If
|
||||||
|
|
||||||
If LOG_HOTSPOTS Then _Logger.Debug("[CreateRowSpecificEditor] Retrieved {0} rows for column [{1}]", oDataTable.Rows.Count, columnName)
|
LOGGER.Debug("[CreateRowSpecificEditor] Retrieved {0} rows for column [{1}]", oDataTable.Rows.Count, columnName)
|
||||||
|
|
||||||
' *** NEU: Log erste 5 Rows für Debugging ***
|
|
||||||
For i As Integer = 0 To Math.Min(4, oDataTable.Rows.Count - 1)
|
|
||||||
If LOG_HOTSPOTS Then _Logger.Debug("[CreateRowSpecificEditor] DataTable Row[{0}]: [{1}]", i, oDataTable.Rows(i)(0))
|
|
||||||
Next
|
|
||||||
|
|
||||||
' Editor erstellen (analog zu GridTables_GetRepositoryItemForColumn)
|
' Editor erstellen (analog zu GridTables_GetRepositoryItemForColumn)
|
||||||
If isAdvancedLookup Then
|
If isAdvancedLookup Then
|
||||||
Dim oEditor = New RepositoryItemLookupControl3 With {
|
Dim oEditor = New RepositoryItemLookupControl3 With {
|
||||||
.DisplayMember = oDataTable.Columns(0).ColumnName,
|
.DisplayMember = oDataTable.Columns(0).ColumnName,
|
||||||
.ValueMember = oDataTable.Columns(0).ColumnName,
|
.ValueMember = oDataTable.Columns(0).ColumnName,
|
||||||
.DataSource = oDataTable
|
.DataSource = oDataTable
|
||||||
}
|
}
|
||||||
_Logger.Debug("[CreateRowSpecificEditor] Created LookupControl3 with DisplayMember=[{0}], ValueMember=[{1}]",
|
_Logger.Debug("[CreateRowSpecificEditor] Created LookupControl3 with DisplayMember=[{0}], ValueMember=[{1}]",
|
||||||
oEditor.DisplayMember, oEditor.ValueMember)
|
oEditor.DisplayMember, oEditor.ValueMember)
|
||||||
Return oEditor
|
Return oEditor
|
||||||
Else
|
Else
|
||||||
Dim oEditor = New RepositoryItemComboBox()
|
Dim oEditor = New RepositoryItemComboBox()
|
||||||
@@ -1618,12 +1680,22 @@ CheckNewItemRow:
|
|||||||
If pView Is Nothing OrElse pArgs Is Nothing OrElse pArgs.Column Is Nothing Then
|
If pView Is Nothing OrElse pArgs Is Nothing OrElse pArgs.Column Is Nothing Then
|
||||||
Return
|
Return
|
||||||
End If
|
End If
|
||||||
|
|
||||||
' *** NEU: Bei Formel-Refresh überspringen ***
|
' *** NEU: Bei Formel-Refresh überspringen ***
|
||||||
If _isRefreshingFormula Then
|
If _isRefreshingFormula Then
|
||||||
_Logger.Debug("Skipping HandleInheritedColumnValue during formula refresh.")
|
_Logger.Debug("Skipping HandleInheritedColumnValue during formula refresh.")
|
||||||
Return
|
Return
|
||||||
End If
|
End If
|
||||||
|
|
||||||
|
' *** NEU: Guard-Prüfung für btnClear-Operationen ***
|
||||||
|
Dim guardKey As String = $"{pView.GetHashCode()}|{pArgs.Column.FieldName}"
|
||||||
|
SyncLock _clearOperationsInProgress
|
||||||
|
If _clearOperationsInProgress.Contains(guardKey) Then
|
||||||
|
_Logger.Debug("[HandleInheritedColumnValue] Clear operation in progress for [{0}] → SKIP inheritance dialog", pArgs.Column.FieldName)
|
||||||
|
Return
|
||||||
|
End If
|
||||||
|
End SyncLock
|
||||||
|
|
||||||
If isApplyingInheritedValue OrElse pArgs.RowHandle = DevExpress.XtraGrid.GridControl.InvalidRowHandle Then
|
If isApplyingInheritedValue OrElse pArgs.RowHandle = DevExpress.XtraGrid.GridControl.InvalidRowHandle Then
|
||||||
If isApplyingInheritedValue Then
|
If isApplyingInheritedValue Then
|
||||||
_Logger.Debug("Currently applying inherited value for column {0} – skipping to prevent recursion.", pArgs.Column.FieldName)
|
_Logger.Debug("Currently applying inherited value for column {0} – skipping to prevent recursion.", pArgs.Column.FieldName)
|
||||||
@@ -1665,7 +1737,7 @@ CheckNewItemRow:
|
|||||||
Dim affectedRowsCount = pView.DataRowCount - listIndex - 1
|
Dim affectedRowsCount = pView.DataRowCount - listIndex - 1
|
||||||
|
|
||||||
Dim confirmationEntry = GetInheritanceConfirmationEntry(pArgs.Column.FieldName)
|
Dim confirmationEntry = GetInheritanceConfirmationEntry(pArgs.Column.FieldName)
|
||||||
|
_Logger.Debug("Inheritance confirmation entry for column {0}: {1}", pArgs.Column.FieldName, confirmationEntry.Count)
|
||||||
If affectedRowsCount > 0 AndAlso confirmationEntry.Count < InheritanceMsgAmount Then
|
If affectedRowsCount > 0 AndAlso confirmationEntry.Count < InheritanceMsgAmount Then
|
||||||
Dim confirmMessage As String = String.Format(
|
Dim confirmMessage As String = String.Format(
|
||||||
"Möchten Sie den Wert '{0}' an {1} nachfolgende Zeile(n) vererben?",
|
"Möchten Sie den Wert '{0}' an {1} nachfolgende Zeile(n) vererben?",
|
||||||
@@ -1758,7 +1830,6 @@ CheckNewItemRow:
|
|||||||
pView.SetRowCellValue(targetHandle, pArgs.Column.FieldName, valueToApply)
|
pView.SetRowCellValue(targetHandle, pArgs.Column.FieldName, valueToApply)
|
||||||
|
|
||||||
' *** SCHRITT 2: Cache-Keys für DIESE Zeile sammeln ***
|
' *** SCHRITT 2: Cache-Keys für DIESE Zeile sammeln ***
|
||||||
' Finde alle dynamischen Spalten, die die geänderte Spalte via {#TBCOL#...} referenzieren
|
|
||||||
For Each dynColName In _DynamicEditorColumns
|
For Each dynColName In _DynamicEditorColumns
|
||||||
Dim oColDef As DataRow = pColumnDefinition.
|
Dim oColDef As DataRow = pColumnDefinition.
|
||||||
Select($"SPALTENNAME = '{dynColName}'").
|
Select($"SPALTENNAME = '{dynColName}'").
|
||||||
@@ -1768,9 +1839,7 @@ CheckNewItemRow:
|
|||||||
|
|
||||||
Dim oSqlCommand As String = oColDef.ItemEx("SQL_COMMAND", "")
|
Dim oSqlCommand As String = oColDef.ItemEx("SQL_COMMAND", "")
|
||||||
|
|
||||||
' Prüfe ob SQL {#TBCOL#<ColumnName>} enthält
|
|
||||||
If oSqlCommand.Contains($"{{#TBCOL#{pArgs.Column.FieldName}}}") Then
|
If oSqlCommand.Contains($"{{#TBCOL#{pArgs.Column.FieldName}}}") Then
|
||||||
' SQL auflösen mit NEUEM Wert (targetHandle!)
|
|
||||||
Try
|
Try
|
||||||
Dim resolvedSql = ResolveSqlTemplate(oSqlCommand, pView, targetHandle)
|
Dim resolvedSql = ResolveSqlTemplate(oSqlCommand, pView, targetHandle)
|
||||||
Dim cacheKey = $"{dynColName}|{resolvedSql.GetHashCode()}"
|
Dim cacheKey = $"{dynColName}|{resolvedSql.GetHashCode()}"
|
||||||
@@ -1809,7 +1878,6 @@ CheckNewItemRow:
|
|||||||
isApplyingInheritedValue = False
|
isApplyingInheritedValue = False
|
||||||
End Try
|
End Try
|
||||||
End Sub
|
End Sub
|
||||||
|
|
||||||
Private Sub SetInheritanceConfirmationCount(columnName As String, newCount As Integer)
|
Private Sub SetInheritanceConfirmationCount(columnName As String, newCount As Integer)
|
||||||
Dim entries = UserInheritance_ConfirmationByColumn
|
Dim entries = UserInheritance_ConfirmationByColumn
|
||||||
If entries Is Nothing Then
|
If entries Is Nothing Then
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user