Skip to content

Commit 77b69e8

Browse files
authored
Make DialogHost only hold weak references to loaded instances (#2437)
1 parent 54664e5 commit 77b69e8

File tree

1 file changed

+32
-7
lines changed

1 file changed

+32
-7
lines changed

MaterialDesignThemes.Wpf/DialogHost.cs

Lines changed: 32 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,7 @@ public class DialogHost : ContentControl
5555
/// </summary>
5656
public static readonly RoutedCommand CloseDialogCommand = new();
5757

58-
private static readonly HashSet<DialogHost> LoadedInstances = new();
58+
private static readonly HashSet<WeakReference<DialogHost>> LoadedInstances = new();
5959

6060
private DialogOpenedEventHandler? _asyncShowOpenedEventHandler;
6161
private DialogClosingEventHandler? _asyncShowClosingEventHandler;
@@ -200,9 +200,24 @@ private static DialogHost GetInstance(object? dialogIdentifier)
200200
{
201201
if (LoadedInstances.Count == 0)
202202
throw new InvalidOperationException("No loaded DialogHost instances.");
203-
LoadedInstances.First().Dispatcher.VerifyAccess();
204203

205-
var targets = LoadedInstances.Where(dh => dialogIdentifier == null || Equals(dh.Identifier, dialogIdentifier)).ToList();
204+
List<DialogHost> targets = new();
205+
foreach(var instance in LoadedInstances.ToList())
206+
{
207+
if (instance.TryGetTarget(out DialogHost? dialogInstance))
208+
{
209+
dialogInstance.Dispatcher.VerifyAccess();
210+
if (dialogIdentifier is null || Equals(dialogIdentifier, dialogInstance.Identifier))
211+
{
212+
targets.Add(dialogInstance);
213+
}
214+
}
215+
else
216+
{
217+
LoadedInstances.Remove(instance);
218+
}
219+
}
220+
206221
if (targets.Count == 0)
207222
throw new InvalidOperationException($"No loaded DialogHost have an {nameof(Identifier)} property matching {nameof(dialogIdentifier)} ('{dialogIdentifier}') argument.");
208223
if (targets.Count > 1)
@@ -671,9 +686,10 @@ internal void InternalClose(object? parameter)
671686

672687
protected override void OnPreviewMouseDown(MouseButtonEventArgs e)
673688
{
674-
var window = Window.GetWindow(this);
675-
if (window != null && !window.IsActive)
689+
if (Window.GetWindow(this) is { } window && !window.IsActive)
690+
{
676691
window.Activate();
692+
}
677693
base.OnPreviewMouseDown(e);
678694
}
679695

@@ -733,10 +749,19 @@ private string GetStateName()
733749
=> IsOpen ? OpenStateName : ClosedStateName;
734750

735751
private void OnUnloaded(object sender, RoutedEventArgs routedEventArgs)
736-
=> LoadedInstances.Remove(this);
752+
{
753+
foreach(var weakRef in LoadedInstances.ToList())
754+
{
755+
if (!weakRef.TryGetTarget(out DialogHost? dialogHost) ||
756+
Equals(dialogHost, this))
757+
{
758+
LoadedInstances.Remove(weakRef);
759+
}
760+
}
761+
}
737762

738763
private void OnLoaded(object sender, RoutedEventArgs routedEventArgs)
739-
=> LoadedInstances.Add(this);
764+
=> LoadedInstances.Add(new WeakReference<DialogHost>(this));
740765

741766
}
742767
}

0 commit comments

Comments
 (0)