diff --git a/src/Avalonia.Layout/AttachedLayout.cs b/src/Avalonia.Layout/AttachedLayout.cs
index 047c01343f..6c884641f8 100644
--- a/src/Avalonia.Layout/AttachedLayout.cs
+++ b/src/Avalonia.Layout/AttachedLayout.cs
@@ -12,17 +12,17 @@ namespace Avalonia.Layout
///
public abstract class AttachedLayout : AvaloniaObject
{
- public string LayoutId { get; set; }
+ public string? LayoutId { get; set; }
///
/// Occurs when the measurement state (layout) has been invalidated.
///
- public event EventHandler MeasureInvalidated;
+ public event EventHandler? MeasureInvalidated;
///
/// Occurs when the arrange state (layout) has been invalidated.
///
- public event EventHandler ArrangeInvalidated;
+ public event EventHandler? ArrangeInvalidated;
///
/// Initializes any per-container state the layout requires when it is attached to an
diff --git a/src/Avalonia.Layout/Avalonia.Layout.csproj b/src/Avalonia.Layout/Avalonia.Layout.csproj
index 2842ccf3a8..c1cd19c394 100644
--- a/src/Avalonia.Layout/Avalonia.Layout.csproj
+++ b/src/Avalonia.Layout/Avalonia.Layout.csproj
@@ -9,4 +9,5 @@
+
diff --git a/src/Avalonia.Layout/ElementManager.cs b/src/Avalonia.Layout/ElementManager.cs
index 681d23a61f..039eb52317 100644
--- a/src/Avalonia.Layout/ElementManager.cs
+++ b/src/Avalonia.Layout/ElementManager.cs
@@ -13,10 +13,10 @@ namespace Avalonia.Layout
{
internal class ElementManager
{
- private readonly List _realizedElements = new List();
+ private readonly List _realizedElements = new List();
private readonly List _realizedElementLayoutBounds = new List();
private int _firstRealizedDataIndex;
- private VirtualizingLayoutContext _context;
+ private VirtualizingLayoutContext? _context;
private bool IsVirtualizingContext
{
@@ -58,7 +58,7 @@ namespace Avalonia.Layout
// Make sure there is enough space for the bounds.
// Note: We could optimize when the count becomes smaller, but keeping
// it always up to date is the simplest option for now.
- _realizedElementLayoutBounds.Resize(count);
+ _realizedElementLayoutBounds.Resize(count, default);
}
}
}
@@ -66,12 +66,12 @@ namespace Avalonia.Layout
public int GetRealizedElementCount()
{
- return IsVirtualizingContext ? _realizedElements.Count : _context.ItemCount;
+ return IsVirtualizingContext ? _realizedElements.Count : _context!.ItemCount;
}
public ILayoutable GetAt(int realizedIndex)
{
- ILayoutable element;
+ ILayoutable? element;
if (IsVirtualizingContext)
{
@@ -80,7 +80,7 @@ namespace Avalonia.Layout
// Sentinel. Create the element now since we need it.
int dataIndex = GetDataIndexFromRealizedRangeIndex(realizedIndex);
Logger.TryGet(LogEventLevel.Verbose, "Repeater")?.Log(this, "Creating element for sentinal with data index {Index}", dataIndex);
- element = _context.GetOrCreateElementAt(
+ element = _context!.GetOrCreateElementAt(
dataIndex,
ElementRealizationOptions.ForceCreate | ElementRealizationOptions.SuppressAutoRecycle);
_realizedElements[realizedIndex] = element;
@@ -93,12 +93,12 @@ namespace Avalonia.Layout
else
{
// realizedIndex and dataIndex are the same (everything is realized)
- element = _context.GetOrCreateElementAt(
+ element = _context!.GetOrCreateElementAt(
realizedIndex,
ElementRealizationOptions.ForceCreate | ElementRealizationOptions.SuppressAutoRecycle);
}
- return element;
+ return element!;
}
public void Add(ILayoutable element, int dataIndex)
@@ -112,7 +112,7 @@ namespace Avalonia.Layout
_realizedElementLayoutBounds.Add(default);
}
- public void Insert(int realizedIndex, int dataIndex, ILayoutable element)
+ public void Insert(int realizedIndex, int dataIndex, ILayoutable? element)
{
if (realizedIndex == 0)
{
@@ -136,7 +136,7 @@ namespace Avalonia.Layout
if (elementRef != null)
{
- _context.RecycleElement(elementRef);
+ _context!.RecycleElement(elementRef);
}
}
@@ -203,26 +203,26 @@ namespace Avalonia.Layout
else
{
// Non virtualized - everything is realized
- return index >= 0 && index < _context.ItemCount;
+ return index >= 0 && index < _context!.ItemCount;
}
}
- public bool IsIndexValidInData(int currentIndex) => (uint)currentIndex < _context.ItemCount;
+ public bool IsIndexValidInData(int currentIndex) => (uint)currentIndex < _context!.ItemCount;
- public ILayoutable GetRealizedElement(int dataIndex)
+ public ILayoutable? GetRealizedElement(int dataIndex)
{
return IsVirtualizingContext ?
GetAt(GetRealizedRangeIndexFromDataIndex(dataIndex)) :
- _context.GetOrCreateElementAt(
+ _context!.GetOrCreateElementAt(
dataIndex,
ElementRealizationOptions.ForceCreate | ElementRealizationOptions.SuppressAutoRecycle);
}
- public void EnsureElementRealized(bool forward, int dataIndex, string layoutId)
+ public void EnsureElementRealized(bool forward, int dataIndex, string? layoutId)
{
if (IsDataIndexRealized(dataIndex) == false)
{
- var element = _context.GetOrCreateElementAt(
+ var element = _context!.GetOrCreateElementAt(
dataIndex,
ElementRealizationOptions.ForceCreate | ElementRealizationOptions.SuppressAutoRecycle);
@@ -273,14 +273,14 @@ namespace Avalonia.Layout
{
case NotifyCollectionChangedAction.Add:
{
- OnItemsAdded(args.NewStartingIndex, args.NewItems.Count);
+ OnItemsAdded(args.NewStartingIndex, args.NewItems!.Count);
}
break;
case NotifyCollectionChangedAction.Replace:
{
- int oldSize = args.OldItems.Count;
- int newSize = args.NewItems.Count;
+ int oldSize = args.OldItems!.Count;
+ int newSize = args.NewItems!.Count;
int oldStartIndex = args.OldStartingIndex;
int newStartIndex = args.NewStartingIndex;
@@ -301,7 +301,7 @@ namespace Avalonia.Layout
if (elementRef != null)
{
- _context.RecycleElement(elementRef);
+ _context!.RecycleElement(elementRef);
_realizedElements[realizedIndex] = null;
}
}
diff --git a/src/Avalonia.Layout/FlowLayoutAlgorithm.cs b/src/Avalonia.Layout/FlowLayoutAlgorithm.cs
index 63343fd1a7..40b392225f 100644
--- a/src/Avalonia.Layout/FlowLayoutAlgorithm.cs
+++ b/src/Avalonia.Layout/FlowLayoutAlgorithm.cs
@@ -16,8 +16,8 @@ namespace Avalonia.Layout
private Size _lastAvailableSize;
private double _lastItemSpacing;
private bool _collectionChangePending;
- private VirtualizingLayoutContext _context;
- private IFlowLayoutAlgorithmDelegates _algorithmCallbacks;
+ private VirtualizingLayoutContext? _context;
+ private IFlowLayoutAlgorithmDelegates? _algorithmCallbacks;
private Rect _lastExtent;
private int _firstRealizedDataIndexInsideRealizationWindow = -1;
private int _lastRealizedDataIndexInsideRealizationWindow = -1;
@@ -46,7 +46,7 @@ namespace Avalonia.Layout
}
}
- private Rect RealizationRect => IsVirtualizingContext ? _context.RealizationRect : new Rect(Size.Infinity);
+ private Rect RealizationRect => IsVirtualizingContext ? _context!.RealizationRect : new Rect(Size.Infinity);
public void InitializeForContext(VirtualizingLayoutContext context, IFlowLayoutAlgorithmDelegates callbacks)
{
@@ -76,7 +76,7 @@ namespace Avalonia.Layout
int maxItemsPerLine,
ScrollOrientation orientation,
bool disableVirtualization,
- string layoutId)
+ string? layoutId)
{
_orientation.ScrollOrientation = orientation;
@@ -87,7 +87,7 @@ namespace Avalonia.Layout
layoutId,
realizationRect);
- var suggestedAnchorIndex = _context.RecommendedAnchorIndex;
+ var suggestedAnchorIndex = _context!.RecommendedAnchorIndex;
if (_elementManager.IsIndexValidInData(suggestedAnchorIndex))
{
var anchorRealized = _elementManager.IsDataIndexRealized(suggestedAnchorIndex);
@@ -124,7 +124,7 @@ namespace Avalonia.Layout
VirtualizingLayoutContext context,
bool isWrapping,
LineAlignment lineAlignment,
- string layoutId)
+ string? layoutId)
{
Logger.TryGet(LogEventLevel.Verbose, "Repeater")?.Log(this, "{LayoutId}: ArrangeLayout", layoutId);
ArrangeVirtualizingLayout(finalSize, lineAlignment, isWrapping, layoutId);
@@ -149,7 +149,7 @@ namespace Avalonia.Layout
Size availableSize,
VirtualizingLayoutContext context)
{
- var measureSize = _algorithmCallbacks.Algorithm_GetMeasureSize(index, availableSize, context);
+ var measureSize = _algorithmCallbacks!.Algorithm_GetMeasureSize(index, availableSize, context);
element.Measure(measureSize);
var provisionalArrangeSize = _algorithmCallbacks.Algorithm_GetProvisionalArrangeSize(index, measureSize, element.DesiredSize, context);
_algorithmCallbacks.Algorithm_OnElementMeasured(element, index, availableSize, measureSize, element.DesiredSize, provisionalArrangeSize, context);
@@ -161,7 +161,7 @@ namespace Avalonia.Layout
Size availableSize,
bool isWrapping,
double minItemSpacing,
- string layoutId)
+ string? layoutId)
{
int anchorIndex = -1;
var anchorPosition= new Point();
@@ -170,7 +170,7 @@ namespace Avalonia.Layout
if (!IsVirtualizingContext)
{
// Non virtualizing host, start generating from the element 0
- anchorIndex = context.ItemCount > 0 ? 0 : -1;
+ anchorIndex = context!.ItemCount > 0 ? 0 : -1;
}
else
{
@@ -183,7 +183,7 @@ namespace Avalonia.Layout
_lastItemSpacing != minItemSpacing ||
_collectionChangePending);
- var suggestedAnchorIndex = _context.RecommendedAnchorIndex;
+ var suggestedAnchorIndex = _context!.RecommendedAnchorIndex;
var isAnchorSuggestionValid = suggestedAnchorIndex >= 0 &&
_elementManager.IsDataIndexRealized(suggestedAnchorIndex);
@@ -191,10 +191,10 @@ namespace Avalonia.Layout
if (isAnchorSuggestionValid)
{
Logger.TryGet(LogEventLevel.Verbose, "Repeater")?.Log(this, "{LayoutId}: Using suggested anchor {Anchor}", layoutId, suggestedAnchorIndex);
- anchorIndex = _algorithmCallbacks.Algorithm_GetAnchorForTargetElement(
+ anchorIndex = _algorithmCallbacks!.Algorithm_GetAnchorForTargetElement(
suggestedAnchorIndex,
availableSize,
- context).Index;
+ context!).Index;
if (_elementManager.IsDataIndexRealized(anchorIndex))
{
@@ -235,7 +235,7 @@ namespace Avalonia.Layout
// The anchor is based on the realization window because a connected ItemsRepeater might intersect the realization window
// but not the visible window. In that situation, we still need to produce a valid anchor.
- var anchorInfo = _algorithmCallbacks.Algorithm_GetAnchorForRealizationRect(availableSize, context);
+ var anchorInfo = _algorithmCallbacks!.Algorithm_GetAnchorForRealizationRect(availableSize, context!);
anchorIndex = anchorInfo.Index;
anchorPosition = _orientation.MinorMajorPoint(0, anchorInfo.Offset);
}
@@ -259,12 +259,12 @@ namespace Avalonia.Layout
Logger.TryGet(LogEventLevel.Verbose, "Repeater")?.Log(this, "{LayoutId} Disconnected Window - throwing away all realized elements", layoutId);
_elementManager.ClearRealizedRange();
- var anchor = _context.GetOrCreateElementAt(anchorIndex, ElementRealizationOptions.ForceCreate | ElementRealizationOptions.SuppressAutoRecycle);
+ var anchor = _context!.GetOrCreateElementAt(anchorIndex, ElementRealizationOptions.ForceCreate | ElementRealizationOptions.SuppressAutoRecycle);
_elementManager.Add(anchor, anchorIndex);
}
var anchorElement = _elementManager.GetRealizedElement(anchorIndex);
- var desiredSize = MeasureElement(anchorElement, anchorIndex, availableSize, _context);
+ var desiredSize = MeasureElement(anchorElement!, anchorIndex, availableSize, _context!);
var layoutBounds = new Rect(anchorPosition.X, anchorPosition.Y, desiredSize.Width, desiredSize.Height);
_elementManager.SetLayoutBoundsForDataIndex(anchorIndex, layoutBounds);
@@ -296,7 +296,7 @@ namespace Avalonia.Layout
double lineSpacing,
int maxItemsPerLine,
bool disableVirtualization,
- string layoutId)
+ string? layoutId)
{
if (anchorIndex != -1)
{
@@ -322,7 +322,7 @@ namespace Avalonia.Layout
// Ensure layout element.
_elementManager.EnsureElementRealized(direction == GenerateDirection.Forward, currentIndex, layoutId);
var currentElement = _elementManager.GetRealizedElement(currentIndex);
- var desiredSize = MeasureElement(currentElement, currentIndex, availableSize, _context);
+ var desiredSize = MeasureElement(currentElement!, currentIndex, availableSize, _context!);
++count;
// Lay it out.
@@ -333,7 +333,7 @@ namespace Avalonia.Layout
if (direction == GenerateDirection.Forward)
{
double remainingSpace = _orientation.Minor(availableSize) - (_orientation.MinorStart(previousElementBounds) + _orientation.MinorSize(previousElementBounds) + minItemSpacing + _orientation.Minor(desiredSize));
- if (countInLine >= maxItemsPerLine || _algorithmCallbacks.Algorithm_ShouldBreakLine(currentIndex, remainingSpace))
+ if (countInLine >= maxItemsPerLine || _algorithmCallbacks!.Algorithm_ShouldBreakLine(currentIndex, remainingSpace))
{
// No more space in this row. wrap to next row.
_orientation.SetMinorStart(ref currentBounds, 0);
@@ -371,7 +371,7 @@ namespace Avalonia.Layout
{
// Backward
double remainingSpace = _orientation.MinorStart(previousElementBounds) - (_orientation.Minor(desiredSize) + minItemSpacing);
- if (countInLine >= maxItemsPerLine || _algorithmCallbacks.Algorithm_ShouldBreakLine(currentIndex, remainingSpace))
+ if (countInLine >= maxItemsPerLine || _algorithmCallbacks!.Algorithm_ShouldBreakLine(currentIndex, remainingSpace))
{
// Does not fit, wrap to the previous row
var availableSizeMinor = _orientation.Minor(availableSize);
@@ -432,13 +432,13 @@ namespace Avalonia.Layout
// account for that element in the indices inside the realization window.
if (direction == GenerateDirection.Forward)
{
- int dataCount = _context.ItemCount;
+ int dataCount = _context!.ItemCount;
_lastRealizedDataIndexInsideRealizationWindow = previousIndex == dataCount - 1 ? dataCount - 1 : previousIndex - 1;
_lastRealizedDataIndexInsideRealizationWindow = Math.Max(0, _lastRealizedDataIndexInsideRealizationWindow);
}
else
{
- int dataCount = _context.ItemCount;
+ int dataCount = _context!.ItemCount;
_firstRealizedDataIndexInsideRealizationWindow = previousIndex == 0 ? 0 : previousIndex + 1;
_firstRealizedDataIndexInsideRealizationWindow = Math.Min(dataCount - 1, _firstRealizedDataIndexInsideRealizationWindow);
}
@@ -454,7 +454,7 @@ namespace Avalonia.Layout
{
_elementManager.ClearRealizedRange();
// FlowLayout requires that the anchor is the first element in the row.
- var internalAnchor = _algorithmCallbacks.Algorithm_GetAnchorForTargetElement(index, availableSize, context);
+ var internalAnchor = _algorithmCallbacks!.Algorithm_GetAnchorForTargetElement(index, availableSize, context);
// No need to set the position of the anchor.
// (0,0) is fine for now since the extent can
@@ -487,7 +487,7 @@ namespace Avalonia.Layout
}
else
{
- var realizationRect = _context.RealizationRect;
+ var realizationRect = _context!.RealizationRect;
var elementBounds = _elementManager.GetLayoutBoundsForDataIndex(index);
var elementMajorStart = _orientation.MajorStart(elementBounds);
@@ -510,11 +510,11 @@ namespace Avalonia.Layout
return shouldContinue;
}
- private Rect EstimateExtent(Size availableSize, string layoutId)
+ private Rect EstimateExtent(Size availableSize, string? layoutId)
{
- ILayoutable firstRealizedElement = null;
+ ILayoutable? firstRealizedElement = null;
Rect firstBounds = new Rect();
- ILayoutable lastRealizedElement = null;
+ ILayoutable? lastRealizedElement = null;
Rect lastBounds = new Rect();
int firstDataIndex = -1;
int lastDataIndex = -1;
@@ -531,9 +531,9 @@ namespace Avalonia.Layout
lastBounds = _elementManager.GetLayoutBoundsForRealizedIndex(last);
}
- Rect extent = _algorithmCallbacks.Algorithm_GetExtent(
+ Rect extent = _algorithmCallbacks!.Algorithm_GetExtent(
availableSize,
- _context,
+ _context!,
firstRealizedElement,
firstDataIndex,
firstBounds,
@@ -563,7 +563,7 @@ namespace Avalonia.Layout
if (_orientation.MajorStart(currentBounds) != currentLineOffset)
{
// Staring a new line
- _algorithmCallbacks.Algorithm_OnLineArranged(currentDataIndex - countInLine, countInLine, currentLineSize, _context);
+ _algorithmCallbacks!.Algorithm_OnLineArranged(currentDataIndex - countInLine, countInLine, currentLineSize, _context!);
countInLine = 0;
currentLineOffset = _orientation.MajorStart(currentBounds);
currentLineSize = 0;
@@ -575,7 +575,7 @@ namespace Avalonia.Layout
}
// Raise for the last line.
- _algorithmCallbacks.Algorithm_OnLineArranged(_lastRealizedDataIndexInsideRealizationWindow - countInLine + 1, countInLine, currentLineSize, _context);
+ _algorithmCallbacks!.Algorithm_OnLineArranged(_lastRealizedDataIndexInsideRealizationWindow - countInLine + 1, countInLine, currentLineSize, _context!);
}
}
}
@@ -584,7 +584,7 @@ namespace Avalonia.Layout
Size finalSize,
LineAlignment lineAlignment,
bool isWrapping,
- string layoutId)
+ string? layoutId)
{
// Walk through the realized elements one line at a time and
// align them, Then call element.Arrange with the arranged bounds.
@@ -636,7 +636,7 @@ namespace Avalonia.Layout
LineAlignment lineAlignment,
bool isWrapping,
Size finalSize,
- string layoutId)
+ string? layoutId)
{
for (int rangeIndex = lineStartIndex; rangeIndex < lineStartIndex + countInLine; ++rangeIndex)
{
@@ -723,11 +723,11 @@ namespace Avalonia.Layout
{
if (IsVirtualizingContext)
{
- _context.LayoutOrigin = new Point(_lastExtent.X, _lastExtent.Y);
+ _context!.LayoutOrigin = new Point(_lastExtent.X, _lastExtent.Y);
}
}
- public ILayoutable GetElementIfRealized(int dataIndex)
+ public ILayoutable? GetElementIfRealized(int dataIndex)
{
if (_elementManager.IsDataIndexRealized(dataIndex))
{
diff --git a/src/Avalonia.Layout/IFlowLayoutAlgorithmDelegates.cs b/src/Avalonia.Layout/IFlowLayoutAlgorithmDelegates.cs
index 907a3adf0f..e3eae0caf7 100644
--- a/src/Avalonia.Layout/IFlowLayoutAlgorithmDelegates.cs
+++ b/src/Avalonia.Layout/IFlowLayoutAlgorithmDelegates.cs
@@ -21,10 +21,10 @@ namespace Avalonia.Layout
Rect Algorithm_GetExtent(
Size availableSize,
VirtualizingLayoutContext context,
- ILayoutable firstRealized,
+ ILayoutable? firstRealized,
int firstRealizedItemIndex,
Rect firstRealizedLayoutBounds,
- ILayoutable lastRealized,
+ ILayoutable? lastRealized,
int lastRealizedItemIndex,
Rect lastRealizedLayoutBounds);
void Algorithm_OnElementMeasured(
diff --git a/src/Avalonia.Layout/LayoutContext.cs b/src/Avalonia.Layout/LayoutContext.cs
index dadce58c0c..90bfc0200c 100644
--- a/src/Avalonia.Layout/LayoutContext.cs
+++ b/src/Avalonia.Layout/LayoutContext.cs
@@ -14,7 +14,7 @@ namespace Avalonia.Layout
///
/// Gets or sets an object that represents the state of a layout.
///
- public object LayoutState
+ public object? LayoutState
{
get => LayoutStateCore;
set => LayoutStateCore = value;
@@ -23,6 +23,6 @@ namespace Avalonia.Layout
///
/// Implements the behavior of in a derived or custom LayoutContext.
///
- protected virtual object LayoutStateCore { get; set; }
+ protected virtual object? LayoutStateCore { get; set; }
}
}
diff --git a/src/Avalonia.Layout/LayoutContextAdapter.cs b/src/Avalonia.Layout/LayoutContextAdapter.cs
index 695866df94..25132c2802 100644
--- a/src/Avalonia.Layout/LayoutContextAdapter.cs
+++ b/src/Avalonia.Layout/LayoutContextAdapter.cs
@@ -16,7 +16,7 @@ namespace Avalonia.Layout
_nonVirtualizingContext = nonVirtualizingContext;
}
- protected override object LayoutStateCore
+ protected override object? LayoutStateCore
{
get => _nonVirtualizingContext.LayoutState;
set => _nonVirtualizingContext.LayoutState = value;
diff --git a/src/Avalonia.Layout/LayoutHelper.cs b/src/Avalonia.Layout/LayoutHelper.cs
index 2fe59b49ca..71a2fa085b 100644
--- a/src/Avalonia.Layout/LayoutHelper.cs
+++ b/src/Avalonia.Layout/LayoutHelper.cs
@@ -101,7 +101,7 @@ namespace Avalonia.Layout
if (result == 0 || double.IsNaN(result) || double.IsInfinity(result))
{
- throw new Exception($"Invalid LayoutScaling returned from {visualRoot.GetType()}");
+ throw new Exception($"Invalid LayoutScaling returned from {visualRoot!.GetType()}");
}
return result;
diff --git a/src/Avalonia.Layout/LayoutQueue.cs b/src/Avalonia.Layout/LayoutQueue.cs
index 1a9eb6b785..24adeb0793 100644
--- a/src/Avalonia.Layout/LayoutQueue.cs
+++ b/src/Avalonia.Layout/LayoutQueue.cs
@@ -5,6 +5,7 @@ using System.Collections.Generic;
namespace Avalonia.Layout
{
internal class LayoutQueue : IReadOnlyCollection, IDisposable
+ where T : notnull
{
private struct Info
{
diff --git a/src/Avalonia.Layout/Layoutable.cs b/src/Avalonia.Layout/Layoutable.cs
index 7568ea8e09..09e0c4263a 100644
--- a/src/Avalonia.Layout/Layoutable.cs
+++ b/src/Avalonia.Layout/Layoutable.cs
@@ -794,7 +794,7 @@ namespace Avalonia.Layout
///
/// The sender.
/// The event args.
- private void LayoutManagedLayoutUpdated(object sender, EventArgs e) => _layoutUpdated?.Invoke(this, e);
+ private void LayoutManagedLayoutUpdated(object? sender, EventArgs e) => _layoutUpdated?.Invoke(this, e);
///
/// Tests whether any of a 's properties include negative values,
diff --git a/src/Avalonia.Layout/NonVirtualizingLayoutContext.cs b/src/Avalonia.Layout/NonVirtualizingLayoutContext.cs
index cef551f32e..91348f5e6d 100644
--- a/src/Avalonia.Layout/NonVirtualizingLayoutContext.cs
+++ b/src/Avalonia.Layout/NonVirtualizingLayoutContext.cs
@@ -12,7 +12,7 @@ namespace Avalonia.Layout
///
public abstract class NonVirtualizingLayoutContext : LayoutContext
{
- private VirtualizingLayoutContext _contextAdapter;
+ private VirtualizingLayoutContext? _contextAdapter;
///
/// Gets the collection of child controls from the container that provides the context.
@@ -26,6 +26,6 @@ namespace Avalonia.Layout
protected abstract IReadOnlyList ChildrenCore { get; }
internal VirtualizingLayoutContext GetVirtualizingContextAdapter() =>
- _contextAdapter ?? (_contextAdapter = new LayoutContextAdapter(this));
+ _contextAdapter ??= new LayoutContextAdapter(this);
}
}
diff --git a/src/Avalonia.Layout/StackLayout.cs b/src/Avalonia.Layout/StackLayout.cs
index 4a93c8344f..32e9c4dc8e 100644
--- a/src/Avalonia.Layout/StackLayout.cs
+++ b/src/Avalonia.Layout/StackLayout.cs
@@ -78,10 +78,10 @@ namespace Avalonia.Layout
internal Rect GetExtent(
Size availableSize,
VirtualizingLayoutContext context,
- ILayoutable firstRealized,
+ ILayoutable? firstRealized,
int firstRealizedItemIndex,
Rect firstRealizedLayoutBounds,
- ILayoutable lastRealized,
+ ILayoutable? lastRealized,
int lastRealizedItemIndex,
Rect lastRealizedLayoutBounds)
{
@@ -89,7 +89,7 @@ namespace Avalonia.Layout
// Constants
int itemsCount = context.ItemCount;
- var stackState = (StackLayoutState)context.LayoutState;
+ var stackState = (StackLayoutState)context.LayoutState!;
double averageElementSize = GetAverageElementSize(availableSize, context, stackState) + Spacing;
_orientation.SetMinorSize(ref extent, stackState.MaxArrangeBounds);
@@ -131,7 +131,7 @@ namespace Avalonia.Layout
{
if (context is VirtualizingLayoutContext virtualContext)
{
- var stackState = (StackLayoutState)virtualContext.LayoutState;
+ var stackState = (StackLayoutState)virtualContext.LayoutState!;
var provisionalArrangeSizeWinRt = provisionalArrangeSize;
stackState.OnElementMeasured(
index,
@@ -177,7 +177,7 @@ namespace Avalonia.Layout
if (targetIndex >= 0 && targetIndex < itemsCount)
{
index = targetIndex;
- var state = (StackLayoutState)context.LayoutState;
+ var state = (StackLayoutState)context.LayoutState!;
double averageElementSize = GetAverageElementSize(availableSize, context, state) + Spacing;
offset = index * averageElementSize + _orientation.MajorStart(state.FlowAlgorithm.LastExtent);
}
@@ -188,10 +188,10 @@ namespace Avalonia.Layout
Rect IFlowLayoutAlgorithmDelegates.Algorithm_GetExtent(
Size availableSize,
VirtualizingLayoutContext context,
- ILayoutable firstRealized,
+ ILayoutable? firstRealized,
int firstRealizedItemIndex,
Rect firstRealizedLayoutBounds,
- ILayoutable lastRealized,
+ ILayoutable? lastRealized,
int lastRealizedItemIndex,
Rect lastRealizedLayoutBounds)
{
@@ -234,7 +234,7 @@ namespace Avalonia.Layout
if (itemsCount > 0)
{
var realizationRect = context.RealizationRect;
- var state = (StackLayoutState)context.LayoutState;
+ var state = (StackLayoutState)context.LayoutState!;
var lastExtent = state.FlowAlgorithm.LastExtent;
double averageElementSize = GetAverageElementSize(availableSize, context, state) + Spacing;
@@ -279,13 +279,13 @@ namespace Avalonia.Layout
protected internal override void UninitializeForContextCore(VirtualizingLayoutContext context)
{
- var stackState = (StackLayoutState)context.LayoutState;
+ var stackState = (StackLayoutState)context.LayoutState!;
stackState.UninitializeForContext(context);
}
protected internal override Size MeasureOverride(VirtualizingLayoutContext context, Size availableSize)
{
- ((StackLayoutState)context.LayoutState).OnMeasureStart();
+ ((StackLayoutState)context.LayoutState!).OnMeasureStart();
var desiredSize = GetFlowAlgorithm(context).Measure(
availableSize,
@@ -358,6 +358,6 @@ namespace Avalonia.Layout
private void InvalidateLayout() => InvalidateMeasure();
- private FlowLayoutAlgorithm GetFlowAlgorithm(VirtualizingLayoutContext context) => ((StackLayoutState)context.LayoutState).FlowAlgorithm;
+ private FlowLayoutAlgorithm GetFlowAlgorithm(VirtualizingLayoutContext context) => ((StackLayoutState)context.LayoutState!).FlowAlgorithm;
}
}
diff --git a/src/Avalonia.Layout/UniformGridLayout.cs b/src/Avalonia.Layout/UniformGridLayout.cs
index 6b147590ab..508113834a 100644
--- a/src/Avalonia.Layout/UniformGridLayout.cs
+++ b/src/Avalonia.Layout/UniformGridLayout.cs
@@ -258,7 +258,7 @@ namespace Avalonia.Layout
Size availableSize,
VirtualizingLayoutContext context)
{
- var gridState = (UniformGridLayoutState)context.LayoutState;
+ var gridState = (UniformGridLayoutState)context.LayoutState!;
return new Size(gridState.EffectiveItemWidth, gridState.EffectiveItemHeight);
}
@@ -268,7 +268,7 @@ namespace Avalonia.Layout
Size desiredSize,
VirtualizingLayoutContext context)
{
- var gridState = (UniformGridLayoutState)context.LayoutState;
+ var gridState = (UniformGridLayoutState)context.LayoutState!;
return new Size(gridState.EffectiveItemWidth, gridState.EffectiveItemHeight);
}
@@ -285,7 +285,7 @@ namespace Avalonia.Layout
var realizationRect = context.RealizationRect;
if (itemsCount > 0 && _orientation.MajorSize(realizationRect) > 0)
{
- var gridState = (UniformGridLayoutState)context.LayoutState;
+ var gridState = (UniformGridLayoutState)context.LayoutState!;
var lastExtent = gridState.FlowAlgorithm.LastExtent;
var itemsPerLine = Math.Min( // note use of unsigned ints
Math.Max(1u, (uint)(_orientation.Minor(availableSize) / GetMinorSizeWithSpacing(context))),
@@ -324,7 +324,7 @@ namespace Avalonia.Layout
Math.Max(1u, _maximumRowsOrColumns));
int indexOfFirstInLine = (targetIndex / itemsPerLine) * itemsPerLine;
index = indexOfFirstInLine;
- var state = context.LayoutState as UniformGridLayoutState;
+ var state = (UniformGridLayoutState)context.LayoutState!;
offset = _orientation.MajorStart(GetLayoutRectForDataIndex(availableSize, indexOfFirstInLine, state.FlowAlgorithm.LastExtent, context));
}
@@ -338,10 +338,10 @@ namespace Avalonia.Layout
Rect IFlowLayoutAlgorithmDelegates.Algorithm_GetExtent(
Size availableSize,
VirtualizingLayoutContext context,
- ILayoutable firstRealized,
+ ILayoutable? firstRealized,
int firstRealizedItemIndex,
Rect firstRealizedLayoutBounds,
- ILayoutable lastRealized,
+ ILayoutable? lastRealized,
int lastRealizedItemIndex,
Rect lastRealizedLayoutBounds)
{
@@ -421,7 +421,7 @@ namespace Avalonia.Layout
protected internal override void UninitializeForContextCore(VirtualizingLayoutContext context)
{
- var gridState = (UniformGridLayoutState)context.LayoutState;
+ var gridState = (UniformGridLayoutState)context.LayoutState!;
gridState.UninitializeForContext(context);
}
@@ -429,7 +429,7 @@ namespace Avalonia.Layout
{
// Set the width and height on the grid state. If the user already set them then use the preset.
// If not, we have to measure the first element and get back a size which we're going to be using for the rest of the items.
- var gridState = (UniformGridLayoutState)context.LayoutState;
+ var gridState = (UniformGridLayoutState)context.LayoutState!;
gridState.EnsureElementSize(availableSize, context, _minItemWidth, _minItemHeight, _itemsStretch, Orientation, MinRowSpacing, MinColumnSpacing, _maximumRowsOrColumns);
var desiredSize = GetFlowAlgorithm(context).Measure(
@@ -467,7 +467,7 @@ namespace Avalonia.Layout
// Always invalidate layout to keep the view accurate.
InvalidateLayout();
- var gridState = (UniformGridLayoutState)context.LayoutState;
+ var gridState = (UniformGridLayoutState)context.LayoutState!;
gridState.ClearElementOnDataSourceChange(context, args);
}
@@ -517,7 +517,7 @@ namespace Avalonia.Layout
private double GetMinorSizeWithSpacing(VirtualizingLayoutContext context)
{
var minItemSpacing = MinItemSpacing;
- var gridState = (UniformGridLayoutState)context.LayoutState;
+ var gridState = (UniformGridLayoutState)context.LayoutState!;
return _orientation.ScrollOrientation == ScrollOrientation.Vertical?
gridState.EffectiveItemWidth + minItemSpacing :
gridState.EffectiveItemHeight + minItemSpacing;
@@ -526,7 +526,7 @@ namespace Avalonia.Layout
private double GetMajorSizeWithSpacing(VirtualizingLayoutContext context)
{
var lineSpacing = LineSpacing;
- var gridState = (UniformGridLayoutState)context.LayoutState;
+ var gridState = (UniformGridLayoutState)context.LayoutState!;
return _orientation.ScrollOrientation == ScrollOrientation.Vertical ?
gridState.EffectiveItemHeight + lineSpacing :
gridState.EffectiveItemWidth + lineSpacing;
@@ -544,7 +544,7 @@ namespace Avalonia.Layout
int rowIndex = (int)(index / itemsPerLine);
int indexInRow = index - (rowIndex * itemsPerLine);
- var gridState = (UniformGridLayoutState)context.LayoutState;
+ var gridState = (UniformGridLayoutState)context.LayoutState!;
Rect bounds = _orientation.MinorMajorRect(
indexInRow * GetMinorSizeWithSpacing(context) + _orientation.MinorStart(lastExtent),
rowIndex * GetMajorSizeWithSpacing(context) + _orientation.MajorStart(lastExtent),
@@ -556,6 +556,6 @@ namespace Avalonia.Layout
private void InvalidateLayout() => InvalidateMeasure();
- private FlowLayoutAlgorithm GetFlowAlgorithm(VirtualizingLayoutContext context) => ((UniformGridLayoutState)context.LayoutState).FlowAlgorithm;
+ private FlowLayoutAlgorithm GetFlowAlgorithm(VirtualizingLayoutContext context) => ((UniformGridLayoutState)context.LayoutState!).FlowAlgorithm;
}
}
diff --git a/src/Avalonia.Layout/UniformGridLayoutState.cs b/src/Avalonia.Layout/UniformGridLayoutState.cs
index 282bbab1a8..d6b5a30bfc 100644
--- a/src/Avalonia.Layout/UniformGridLayoutState.cs
+++ b/src/Avalonia.Layout/UniformGridLayoutState.cs
@@ -18,7 +18,7 @@ namespace Avalonia.Layout
// If it does not, then we need to do context.GetElement(0) at which point we have requested an element and are on point to clear it.
// If we are responsible for clearing element 0 we keep m_cachedFirstElement valid.
// If we are not (because FlowLayoutAlgorithm is holding it for us) then we just null out this field and use the one from FlowLayoutAlgorithm.
- private ILayoutable _cachedFirstElement;
+ private ILayoutable? _cachedFirstElement;
internal FlowLayoutAlgorithm FlowAlgorithm { get; } = new FlowLayoutAlgorithm();
internal double EffectiveItemWidth { get; private set; }
diff --git a/src/Avalonia.Layout/Utils/ListUtils.cs b/src/Avalonia.Layout/Utils/ListUtils.cs
index eb2480acd3..9ca8bb0525 100644
--- a/src/Avalonia.Layout/Utils/ListUtils.cs
+++ b/src/Avalonia.Layout/Utils/ListUtils.cs
@@ -23,10 +23,5 @@ namespace Avalonia.Layout.Utils
list.AddRange(Enumerable.Repeat(value, size - cur));
}
}
-
- public static void Resize(this List list, int count)
- {
- Resize(list, count, default);
- }
}
}
diff --git a/src/Avalonia.Layout/VirtualLayoutContextAdapter.cs b/src/Avalonia.Layout/VirtualLayoutContextAdapter.cs
index 80ccee2114..f068187523 100644
--- a/src/Avalonia.Layout/VirtualLayoutContextAdapter.cs
+++ b/src/Avalonia.Layout/VirtualLayoutContextAdapter.cs
@@ -6,14 +6,14 @@ namespace Avalonia.Layout
public class VirtualLayoutContextAdapter : NonVirtualizingLayoutContext
{
private readonly VirtualizingLayoutContext _virtualizingContext;
- private ChildrenCollection _children;
+ private ChildrenCollection? _children;
public VirtualLayoutContextAdapter(VirtualizingLayoutContext virtualizingContext)
{
_virtualizingContext = virtualizingContext;
}
- protected override object LayoutStateCore
+ protected override object? LayoutStateCore
{
get => _virtualizingContext.LayoutState;
set => _virtualizingContext.LayoutState = value;
diff --git a/src/Avalonia.Layout/VirtualizingLayoutContext.cs b/src/Avalonia.Layout/VirtualizingLayoutContext.cs
index 079b91a90f..f48c9b0ef2 100644
--- a/src/Avalonia.Layout/VirtualizingLayoutContext.cs
+++ b/src/Avalonia.Layout/VirtualizingLayoutContext.cs
@@ -43,7 +43,7 @@ namespace Avalonia.Layout
///
public abstract class VirtualizingLayoutContext : LayoutContext
{
- private NonVirtualizingLayoutContext _contextAdapter;
+ private NonVirtualizingLayoutContext? _contextAdapter;
///
/// Gets the number of items in the data.
diff --git a/src/Avalonia.Layout/WrapLayout/UvMeasure.cs b/src/Avalonia.Layout/WrapLayout/UvMeasure.cs
index e10e6bd0f8..91fa459acb 100644
--- a/src/Avalonia.Layout/WrapLayout/UvMeasure.cs
+++ b/src/Avalonia.Layout/WrapLayout/UvMeasure.cs
@@ -27,7 +27,7 @@ namespace Avalonia.Layout
}
}
- public override bool Equals(object obj)
+ public override bool Equals(object? obj)
{
if (obj is UvMeasure measure)
{
diff --git a/src/Avalonia.Layout/WrapLayout/WrapItem.cs b/src/Avalonia.Layout/WrapLayout/WrapItem.cs
index 2f0b39a2d1..e823ade6d4 100644
--- a/src/Avalonia.Layout/WrapLayout/WrapItem.cs
+++ b/src/Avalonia.Layout/WrapLayout/WrapItem.cs
@@ -20,6 +20,6 @@ namespace Avalonia.Layout
public UvMeasure? Position { get; internal set; }
- public ILayoutable Element { get; internal set; }
+ public ILayoutable? Element { get; internal set; }
}
}
diff --git a/src/Avalonia.Layout/WrapLayout/WrapLayout.cs b/src/Avalonia.Layout/WrapLayout/WrapLayout.cs
index ded2afc3dd..d12a83d1d7 100644
--- a/src/Avalonia.Layout/WrapLayout/WrapLayout.cs
+++ b/src/Avalonia.Layout/WrapLayout/WrapLayout.cs
@@ -88,7 +88,7 @@ namespace Avalonia.Layout
///
protected internal override void OnItemsChangedCore(VirtualizingLayoutContext context, object source, NotifyCollectionChangedEventArgs args)
{
- var state = (WrapLayoutState)context.LayoutState;
+ var state = (WrapLayoutState)context.LayoutState!;
switch (args.Action)
{
@@ -126,7 +126,7 @@ namespace Avalonia.Layout
var realizationBounds = new UvBounds(Orientation, context.RealizationRect);
var position = UvMeasure.Zero;
- var state = (WrapLayoutState)context.LayoutState;
+ var state = (WrapLayoutState)context.LayoutState!;
if (state.Orientation != Orientation)
{
state.SetOrientation(Orientation);
@@ -261,7 +261,7 @@ namespace Avalonia.Layout
var spacingMeasure = new UvMeasure(Orientation, HorizontalSpacing, VerticalSpacing);
var realizationBounds = new UvBounds(Orientation, context.RealizationRect);
- var state = (WrapLayoutState)context.LayoutState;
+ var state = (WrapLayoutState)context.LayoutState!;
bool Arrange(WrapItem item, bool isLast = false)
{
if (item.Measure.HasValue == false)
diff --git a/src/Avalonia.Layout/WrapLayout/WrapLayoutState.cs b/src/Avalonia.Layout/WrapLayout/WrapLayoutState.cs
index 7955ea983c..720ab96830 100644
--- a/src/Avalonia.Layout/WrapLayout/WrapLayoutState.cs
+++ b/src/Avalonia.Layout/WrapLayout/WrapLayoutState.cs
@@ -62,8 +62,11 @@ namespace Avalonia.Layout
internal void SetOrientation(Orientation orientation)
{
- foreach (var item in _items.Where(i => i.Measure.HasValue))
+ foreach (var item in _items)
{
+ if (!item.Measure.HasValue)
+ continue;
+
UvMeasure measure = item.Measure.Value;
double v = measure.V;
measure.V = measure.U;
@@ -120,10 +123,10 @@ namespace Avalonia.Layout
}
lastPosition = item.Position;
- maxV = Math.Max(maxV, item.Measure.Value.V);
+ maxV = Math.Max(maxV, item.Measure!.Value.V);
}
- double totalHeight = lastPosition.Value.V + maxV;
+ double totalHeight = lastPosition!.Value.V + maxV;
if (calculateAverage)
{
return (totalHeight / itemCount) * _context.ItemCount;