mirror of
https://github.com/AtomUI/AtomUI.git
synced 2026-10-16 21:21:03 +08:00
feat(Dialog): improve closing logic and ensure proper cleanup of dialog state
This commit is contained in:
+1
-1
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"sdk": {
|
||||
"version": "10.0.301",
|
||||
"version": "10.0.300",
|
||||
"rollForward": "latestFeature"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -605,6 +605,7 @@ public partial class Dialog : TemplatedControl,
|
||||
}
|
||||
|
||||
_closing = true;
|
||||
var closeCompletionPending = false;
|
||||
try
|
||||
{
|
||||
if (Result is DialogCode code)
|
||||
@@ -625,28 +626,50 @@ public partial class Dialog : TemplatedControl,
|
||||
dialogAwareDataContext.NotifyClosed();
|
||||
}
|
||||
|
||||
var result = Result;
|
||||
var openState = _openState;
|
||||
_openState = null;
|
||||
_openState = null;
|
||||
_dialogHostChangedHandler?.Invoke(null);
|
||||
openState?.Dispose();
|
||||
|
||||
using (BeginIgnoringIsOpen())
|
||||
{
|
||||
SetCurrentValue(IsOpenProperty, false);
|
||||
}
|
||||
|
||||
Closed?.Invoke(this, EventArgs.Empty);
|
||||
_frameCancellationTokenSource?.Cancel();
|
||||
_frameCancellationTokenSource?.Dispose();
|
||||
_frameCancellationTokenSource = null;
|
||||
openState?.SetClosed(Result);
|
||||
if (openState is not null)
|
||||
{
|
||||
var closeCompletedSynchronously = false;
|
||||
openState.Close(() =>
|
||||
{
|
||||
closeCompletedSynchronously = true;
|
||||
CompleteClose(openState, result);
|
||||
});
|
||||
closeCompletionPending = !closeCompletedSynchronously;
|
||||
}
|
||||
else
|
||||
{
|
||||
CompleteClose(null, result);
|
||||
}
|
||||
}
|
||||
finally
|
||||
{
|
||||
_closing = false;
|
||||
if (!closeCompletionPending)
|
||||
{
|
||||
_closing = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void CompleteClose(DialogOpenState? openState, object? result)
|
||||
{
|
||||
openState?.SetClosed(result);
|
||||
Closed?.Invoke(this, EventArgs.Empty);
|
||||
_frameCancellationTokenSource?.Cancel();
|
||||
_frameCancellationTokenSource?.Dispose();
|
||||
_frameCancellationTokenSource = null;
|
||||
_closing = false;
|
||||
}
|
||||
|
||||
protected override void OnPropertyChanged(AvaloniaPropertyChangedEventArgs change)
|
||||
{
|
||||
base.OnPropertyChanged(change);
|
||||
@@ -804,7 +827,8 @@ public partial class Dialog : TemplatedControl,
|
||||
private class DialogOpenState : IDisposable
|
||||
{
|
||||
private readonly IDisposable _cleanup;
|
||||
private readonly TaskCompletionSource<object?> _closedTaskSource = new();
|
||||
private readonly TaskCompletionSource<object?> _closedTaskSource =
|
||||
new(TaskCreationOptions.RunContinuationsAsynchronously);
|
||||
|
||||
public DialogOpenState(IDialogHost dialogHost,
|
||||
IDisposable cleanup)
|
||||
@@ -821,10 +845,19 @@ public partial class Dialog : TemplatedControl,
|
||||
_closedTaskSource.TrySetResult(result);
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
public void Close(Action? closedCallback = null)
|
||||
{
|
||||
_cleanup.Dispose();
|
||||
DialogHost.Close(() => DialogHost.Content = null);
|
||||
DialogHost.Close(() =>
|
||||
{
|
||||
DialogHost.Content = null;
|
||||
closedCallback?.Invoke();
|
||||
});
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
Close();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -291,11 +291,17 @@ internal class DialogHost : Window,
|
||||
_confirmLoadingBindings?.Dispose();
|
||||
_confirmLoadingBindings = null;
|
||||
_dialogContent.ReleaseButtonBox();
|
||||
Closed += HandleClosed;
|
||||
base.Close();
|
||||
// 与 BindDialog 里 SetParent(dialog) 对称:释放 Dialog ↔ DialogHost 的 logical
|
||||
// parent/child 引用,避免关闭后双方互锁无法 GC。
|
||||
((ISetLogicalParent)this).SetParent(null);
|
||||
callback?.Invoke();
|
||||
|
||||
void HandleClosed(object? sender, EventArgs args)
|
||||
{
|
||||
Closed -= HandleClosed;
|
||||
// 与 BindDialog 里 SetParent(dialog) 对称:释放 Dialog ↔ DialogHost 的 logical
|
||||
// parent/child 引用,避免关闭后双方互锁无法 GC。
|
||||
((ISetLogicalParent)this).SetParent(null);
|
||||
callback?.Invoke();
|
||||
}
|
||||
}
|
||||
|
||||
private void BindContentProperties()
|
||||
|
||||
Reference in New Issue
Block a user