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

56
src/Avalonia.Controls/WindowBase.cs

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