Browse Source

Use EffectiveViewportChanged in ViewportManager.

pull/4173/head
Steven Kirk 6 years ago
parent
commit
4b503f8b37
  1. 45
      src/Avalonia.Controls/Repeater/ViewportManager.cs

45
src/Avalonia.Controls/Repeater/ViewportManager.cs

@ -49,8 +49,8 @@ namespace Avalonia.Controls
// For non-virtualizing layouts, we do not need to keep
// updating viewports and invalidating measure often. So when
// a non virtualizing layout is used, we stop doing all that work.
bool _managingViewportDisabled;
private IDisposable _effectiveViewportChangedRevoker;
private bool _managingViewportDisabled;
private bool _effectiveViewportChangedSubscribed;
private bool _layoutUpdatedSubscribed;
public ViewportManager(ItemsRepeater owner)
@ -228,11 +228,15 @@ namespace Avalonia.Controls
_pendingViewportShift = default;
_unshiftableShift = default;
_effectiveViewportChangedRevoker?.Dispose();
if (!_managingViewportDisabled)
if (_managingViewportDisabled && _effectiveViewportChangedSubscribed)
{
_effectiveViewportChangedRevoker = SubscribeToEffectiveViewportChanged(_owner);
_owner.EffectiveViewportChanged -= OnEffectiveViewportChanged;
_effectiveViewportChangedSubscribed = false;
}
else if (!_managingViewportDisabled && !_effectiveViewportChangedSubscribed)
{
_owner.EffectiveViewportChanged += OnEffectiveViewportChanged;
_effectiveViewportChangedSubscribed = true;
}
}
@ -415,15 +419,15 @@ namespace Avalonia.Controls
_scroller = null;
}
_effectiveViewportChangedRevoker?.Dispose();
_effectiveViewportChangedRevoker = null;
_owner.EffectiveViewportChanged -= OnEffectiveViewportChanged;
_effectiveViewportChangedSubscribed = false;
_ensuredScroller = false;
}
private void OnEffectiveViewportChanged(Rect effectiveViewport)
private void OnEffectiveViewportChanged(object sender, EffectiveViewportChangedEventArgs e)
{
Logger.TryGet(LogEventLevel.Verbose, "Repeater")?.Log(this, "{LayoutId}: EffectiveViewportChanged event callback", _owner.Layout.LayoutId);
UpdateViewport(effectiveViewport);
UpdateViewport(e.EffectiveViewport);
_pendingViewportShift = default;
_unshiftableShift = default;
@ -468,8 +472,8 @@ namespace Avalonia.Controls
}
else if (!_managingViewportDisabled)
{
_effectiveViewportChangedRevoker?.Dispose();
_effectiveViewportChangedRevoker = SubscribeToEffectiveViewportChanged(_owner);
_owner.EffectiveViewportChanged += OnEffectiveViewportChanged;
_effectiveViewportChangedSubscribed = true;
}
_ensuredScroller = true;
@ -541,26 +545,15 @@ namespace Avalonia.Controls
// UWP uses the EffectiveViewportChanged event (which I think was implemented specially
// for this case): we need to implement that in Avalonia, but the semantics of it aren't
// clear to me. Hopefully the source for this event will be released with WinUI 3.
if (control.VisualParent is ScrollContentPresenter scp)
if (control.VisualParent is Layoutable layoutable)
{
scp.PreArrange += ScrollContentPresenterPreArrange;
return Disposable.Create(() => scp.PreArrange -= ScrollContentPresenterPreArrange);
layoutable.EffectiveViewportChanged += OnEffectiveViewportChanged;
return Disposable.Create(() => layoutable.EffectiveViewportChanged -= OnEffectiveViewportChanged);
}
return Disposable.Empty;
}
private void ScrollContentPresenterPreArrange(object sender, VectorEventArgs e)
{
var scp = (ScrollContentPresenter)sender;
var effectiveViewport = new Rect((Point)scp.Offset, new Size(e.Vector.X, e.Vector.Y));
if (effectiveViewport != _visibleWindow)
{
OnEffectiveViewportChanged(effectiveViewport);
}
}
private class ScrollerInfo
{
public ScrollerInfo(ScrollViewer scroller)

Loading…
Cancel
Save