fix(reorder): trap layer-list drag drop as a data change and persist it

List_PreviewMouseMove reorders StagedScene.Elements via RemoveAt/Insert,
bypassing SceneGraph's mutation surface, but never scheduled a save — the
new z-order was lost on restart. The drop now sets _dragReordered and
EndListDrag funnels it through MainViewModel.OnSceneElementsReordered()
(InvalidateBake + ScheduleSave, same background-save path as every other
mutation). Integration test (RealApp + temp DB) reproduces the exact
code-behind mutation and asserts the debounced save lands the new Source
SortOrder. Derivation reference: standard WPF ItemsControl drag-reorder
pattern (OBS layering semantics: bottom-most layer = index 0).
This commit is contained in:
2026-09-18 08:18:51 -07:00
parent fd5198df9f
commit c11788574e
4 changed files with 197 additions and 10 deletions
+7
View File
@@ -20,6 +20,7 @@ public partial class LeftPanel : UserControl
private int _dragIndex = -1;
private bool _isDragging;
private object? _lastHoveredItem;
private bool _dragReordered;
public LeftPanel()
{
@@ -159,6 +160,7 @@ public partial class LeftPanel : UserControl
_dragStartPoint = e.GetPosition(listBox);
_isDragging = false;
_lastHoveredItem = null;
_dragReordered = false;
}
private void List_PreviewMouseMove(object sender, MouseEventArgs e)
@@ -196,6 +198,7 @@ public partial class LeftPanel : UserControl
items.Insert(targetIndex, dragged);
_dragIndex = targetIndex;
_lastHoveredItem = targetItem;
_dragReordered = true;
}
private void List_PreviewMouseLeftButtonUp(object sender, MouseButtonEventArgs e)
@@ -207,9 +210,13 @@ public partial class LeftPanel : UserControl
{
if (_isDragging)
listBox.ReleaseMouseCapture();
var reordered = _dragReordered;
_dragIndex = -1;
_isDragging = false;
_lastHoveredItem = null;
_dragReordered = false;
if (reordered && DataContext is MainViewModel vm)
vm.OnSceneElementsReordered();
}
private static ListBoxItem? FindItemContainerAt(ListBox listBox, Point position)