Browse Source

use disposable pattern to make logic more robust.

pull/9562/head
Dan Walmsley 4 years ago
parent
commit
65d6eccc94
  1. 34
      src/Avalonia.Controls/Window.cs
  2. 56
      src/Avalonia.Controls/WindowBase.cs

34
src/Avalonia.Controls/Window.cs

@ -567,10 +567,8 @@ namespace Avalonia.Controls
/// </summary> /// </summary>
public override void Hide() public override void Hide()
{ {
try using (FreezeVisibilityChangeHandling())
{ {
IgnoreVisibilityChange = true;
if (!_shown) if (!_shown)
{ {
return; return;
@ -596,10 +594,6 @@ namespace Avalonia.Controls
IsVisible = false; IsVisible = false;
_shown = false; _shown = false;
} }
finally
{
IgnoreVisibilityChange = false;
}
} }
/// <summary> /// <summary>
@ -615,7 +609,7 @@ namespace Avalonia.Controls
protected override void IsVisibleChanged(AvaloniaPropertyChangedEventArgs e) protected override void IsVisibleChanged(AvaloniaPropertyChangedEventArgs e)
{ {
if (!IgnoreVisibilityChange) if (!IgnoreVisibilityChanges)
{ {
var isVisible = e.GetNewValue<bool>(); var isVisible = e.GetNewValue<bool>();
@ -685,12 +679,10 @@ namespace Avalonia.Controls
private void ShowCore(Window? owner) private void ShowCore(Window? owner)
{ {
try using (FreezeVisibilityChangeHandling())
{ {
IgnoreVisibilityChange = true;
EnsureStateBeforeShow(); EnsureStateBeforeShow();
if (owner != null) if (owner != null)
{ {
EnsureParentStateBeforeShow(owner); EnsureParentStateBeforeShow(owner);
@ -733,10 +725,6 @@ namespace Avalonia.Controls
Renderer?.Start(); Renderer?.Start();
OnOpened(EventArgs.Empty); OnOpened(EventArgs.Empty);
} }
finally
{
IgnoreVisibilityChange = false;
}
} }
/// <summary> /// <summary>
@ -766,19 +754,17 @@ namespace Avalonia.Controls
/// </returns> /// </returns>
public Task<TResult> ShowDialog<TResult>(Window owner) public Task<TResult> ShowDialog<TResult>(Window owner)
{ {
try using (FreezeVisibilityChangeHandling())
{ {
IgnoreVisibilityChange = true;
EnsureStateBeforeShow(); EnsureStateBeforeShow();
if (owner == null) if (owner == null)
{ {
throw new ArgumentNullException(nameof(owner)); throw new ArgumentNullException(nameof(owner));
} }
EnsureParentStateBeforeShow(owner); EnsureParentStateBeforeShow(owner);
if (_shown) if (_shown)
{ {
throw new InvalidOperationException("The window is already being shown."); throw new InvalidOperationException("The window is already being shown.");
@ -828,10 +814,6 @@ namespace Avalonia.Controls
OnOpened(EventArgs.Empty); OnOpened(EventArgs.Empty);
return result.Task; return result.Task;
} }
finally
{
IgnoreVisibilityChange = false;
}
} }
private void UpdateEnabled() private void UpdateEnabled()

56
src/Avalonia.Controls/WindowBase.cs

@ -42,9 +42,11 @@ namespace Avalonia.Controls
private bool _hasExecutedInitialLayoutPass; private bool _hasExecutedInitialLayoutPass;
private bool _isActive; private bool _isActive;
protected bool IgnoreVisibilityChange { get; set; } private int _ignoreVisibilityChanges;
private WindowBase? _owner; private WindowBase? _owner;
protected bool IgnoreVisibilityChanges => _ignoreVisibilityChanges > 0;
static WindowBase() static WindowBase()
{ {
IsVisibleProperty.OverrideDefaultValue<WindowBase>(false); IsVisibleProperty.OverrideDefaultValue<WindowBase>(false);
@ -66,6 +68,11 @@ namespace Avalonia.Controls
impl.PositionChanged = HandlePositionChanged; impl.PositionChanged = HandlePositionChanged;
} }
protected IDisposable FreezeVisibilityChangeHandling()
{
return new IgnoreVisibilityChangesDisposable(this);
}
/// <summary> /// <summary>
/// Fired when the window is activated. /// Fired when the window is activated.
/// </summary> /// </summary>
@ -125,18 +132,12 @@ namespace Avalonia.Controls
/// </summary> /// </summary>
public virtual void Hide() public virtual void Hide()
{ {
IgnoreVisibilityChange = true; using (FreezeVisibilityChangeHandling())
try
{ {
Renderer?.Stop(); Renderer?.Stop();
PlatformImpl?.Hide(); PlatformImpl?.Hide();
IsVisible = false; IsVisible = false;
} }
finally
{
IgnoreVisibilityChange = false;
}
} }
/// <summary> /// <summary>
@ -144,9 +145,7 @@ namespace Avalonia.Controls
/// </summary> /// </summary>
public virtual void Show() public virtual void Show()
{ {
IgnoreVisibilityChange = true; using (FreezeVisibilityChangeHandling())
try
{ {
EnsureInitialized(); EnsureInitialized();
ApplyStyling(); ApplyStyling();
@ -157,14 +156,11 @@ namespace Avalonia.Controls
LayoutManager.ExecuteInitialLayoutPass(); LayoutManager.ExecuteInitialLayoutPass();
_hasExecutedInitialLayoutPass = true; _hasExecutedInitialLayoutPass = true;
} }
PlatformImpl?.Show(true, false); PlatformImpl?.Show(true, false);
Renderer?.Start(); Renderer?.Start();
OnOpened(EventArgs.Empty); OnOpened(EventArgs.Empty);
} }
finally
{
IgnoreVisibilityChange = false;
}
} }
/// <summary> /// <summary>
@ -202,23 +198,17 @@ namespace Avalonia.Controls
protected override void HandleClosed() protected override void HandleClosed()
{ {
IgnoreVisibilityChange = true; using (FreezeVisibilityChangeHandling())
try
{ {
IsVisible = false; IsVisible = false;
if (this is IFocusScope scope) if (this is IFocusScope scope)
{ {
FocusManager.Instance?.RemoveFocusScope(scope); FocusManager.Instance?.RemoveFocusScope(scope);
} }
base.HandleClosed(); base.HandleClosed();
} }
finally
{
IgnoreVisibilityChange = false;
}
} }
/// <summary> /// <summary>
@ -320,7 +310,7 @@ namespace Avalonia.Controls
protected virtual void IsVisibleChanged(AvaloniaPropertyChangedEventArgs e) protected virtual void IsVisibleChanged(AvaloniaPropertyChangedEventArgs e)
{ {
if (!IgnoreVisibilityChange) if (_ignoreVisibilityChanges == 0)
{ {
if ((bool)e.NewValue!) if ((bool)e.NewValue!)
{ {
@ -332,5 +322,21 @@ namespace Avalonia.Controls
} }
} }
} }
private readonly struct IgnoreVisibilityChangesDisposable : IDisposable
{
private readonly WindowBase _windowBase;
public IgnoreVisibilityChangesDisposable(WindowBase windowBase)
{
_windowBase = windowBase;
_windowBase._ignoreVisibilityChanges++;
}
public void Dispose()
{
_windowBase._ignoreVisibilityChanges--;
}
}
} }
} }

Loading…
Cancel
Save