diff --git a/azure-pipelines.yml b/azure-pipelines.yml
index 15392278c9..fbd8507193 100644
--- a/azure-pipelines.yml
+++ b/azure-pipelines.yml
@@ -51,7 +51,7 @@ jobs:
inputs:
actions: 'build'
scheme: ''
- sdk: 'macosx11.0'
+ sdk: 'macosx11.1'
configuration: 'Release'
xcWorkspacePath: '**/*.xcodeproj/project.xcworkspace'
xcodeVersion: '12' # Options: 8, 9, default, specifyPath
diff --git a/build/SharedVersion.props b/build/SharedVersion.props
index 43ec995ed9..9a268a21e7 100644
--- a/build/SharedVersion.props
+++ b/build/SharedVersion.props
@@ -21,6 +21,6 @@
-
+
diff --git a/native/Avalonia.Native/src/OSX/rendertarget.mm b/native/Avalonia.Native/src/OSX/rendertarget.mm
index 00b6dab219..b2d4341bb9 100644
--- a/native/Avalonia.Native/src/OSX/rendertarget.mm
+++ b/native/Avalonia.Native/src/OSX/rendertarget.mm
@@ -111,7 +111,11 @@
if(_renderbuffer != 0)
glDeleteRenderbuffers(1, &_renderbuffer);
}
- CFRelease(surface);
+
+ if(surface != nullptr)
+ {
+ CFRelease(surface);
+ }
}
@end
@@ -145,6 +149,12 @@ static IAvnGlSurfaceRenderTarget* CreateGlRenderTarget(IOSurfaceRenderTarget* ta
}
- (void)resize:(AvnPixelSize)size withScale: (float) scale{
+
+ if(size.Height <= 0)
+ size.Height = 1;
+ if(size.Width <= 0)
+ size.Width = 1;
+
@synchronized (lock) {
if(surface == nil
|| surface->size.Width != size.Width
diff --git a/src/Avalonia.Controls.DataGrid/DataGrid.cs b/src/Avalonia.Controls.DataGrid/DataGrid.cs
index 5bb2763566..6687c59aa4 100644
--- a/src/Avalonia.Controls.DataGrid/DataGrid.cs
+++ b/src/Avalonia.Controls.DataGrid/DataGrid.cs
@@ -1,6 +1,6 @@
// This source is subject to the Microsoft Public License (Ms-PL).
// Please see http://go.microsoft.com/fwlink/?LinkID=131993 for details.
-// All other rights reserved.
+// All other rights reserved.
using Avalonia.Collections;
using Avalonia.Controls.Primitives;
@@ -92,7 +92,7 @@ namespace Avalonia.Controls
private ContentControl _topRightCornerHeader;
private Control _frozenColumnScrollBarSpacer;
- // the sum of the widths in pixels of the scrolling columns preceding
+ // the sum of the widths in pixels of the scrolling columns preceding
// the first displayed scrolling column
private double _horizontalOffset;
@@ -143,7 +143,7 @@ namespace Avalonia.Controls
private object _uneditedValue; // Represents the original current cell value at the time it enters editing mode.
private ICellEditBinding _currentCellEditBinding;
- // An approximation of the sum of the heights in pixels of the scrolling rows preceding
+ // An approximation of the sum of the heights in pixels of the scrolling rows preceding
// the first displayed scrolling row. Since the scrolled off rows are discarded, the grid
// does not know their actual height. The heights used for the approximation are the ones
// set as the rows were scrolled off.
@@ -162,7 +162,7 @@ namespace Avalonia.Controls
AvaloniaProperty.Register(nameof(CanUserReorderColumns));
///
- /// Gets or sets a value that indicates whether the user can change
+ /// Gets or sets a value that indicates whether the user can change
/// the column display order by dragging column headers with the mouse.
///
public bool CanUserReorderColumns
@@ -247,8 +247,8 @@ namespace Avalonia.Controls
/// Gets or sets the that is used to paint the background of odd-numbered rows.
///
///
- /// The brush that is used to paint the background of odd-numbered rows. The default is a
- /// with a
+ /// The brush that is used to paint the background of odd-numbered rows. The default is a
+ /// with a
/// value of white (ARGB value #00FFFFFF).
///
public IBrush AlternatingRowBackground
@@ -379,8 +379,8 @@ namespace Avalonia.Controls
public bool IsValid
{
get { return _isValid; }
- internal set
- {
+ internal set
+ {
SetAndRaise(IsValidProperty, ref _isValid, value);
PseudoClasses.Set(":invalid", !value);
}
@@ -398,7 +398,7 @@ namespace Avalonia.Controls
}
///
- /// Gets or sets the maximum width of columns in the .
+ /// Gets or sets the maximum width of columns in the .
///
public double MaxColumnWidth
{
@@ -418,7 +418,7 @@ namespace Avalonia.Controls
}
///
- /// Gets or sets the minimum width of columns in the .
+ /// Gets or sets the minimum width of columns in the .
///
public double MinColumnWidth
{
@@ -496,7 +496,7 @@ namespace Avalonia.Controls
AvaloniaProperty.Register(nameof(VerticalGridLinesBrush));
///
- /// Gets or sets the that is used to paint grid lines separating columns.
+ /// Gets or sets the that is used to paint grid lines separating columns.
///
public IBrush VerticalGridLinesBrush
{
@@ -542,7 +542,7 @@ namespace Avalonia.Controls
///
///
/// The index of the current selection, or -1 if the selection is empty.
- ///
+ ///
public int SelectedIndex
{
get { return _selectedIndex; }
@@ -582,7 +582,7 @@ namespace Avalonia.Controls
AvaloniaProperty.Register(nameof(AutoGenerateColumns));
///
- /// Gets or sets a value that indicates whether columns are created
+ /// Gets or sets a value that indicates whether columns are created
/// automatically when the property is set.
///
public bool AutoGenerateColumns
@@ -626,7 +626,7 @@ namespace Avalonia.Controls
AvaloniaProperty.Register(nameof(AreRowDetailsFrozen));
///
- /// Gets or sets a value that indicates whether the row details sections remain
+ /// Gets or sets a value that indicates whether the row details sections remain
/// fixed at the width of the display area or can scroll horizontally.
///
public bool AreRowDetailsFrozen
@@ -881,7 +881,7 @@ namespace Avalonia.Controls
{
int index = (int)e.NewValue;
- // GetDataItem returns null if index is >= Count, we do not check newValue
+ // GetDataItem returns null if index is >= Count, we do not check newValue
// against Count here to avoid enumerating through an Enumerable twice
// Setting SelectedItem coerces the finally value of the SelectedIndex
object newSelectedItem = (index < 0) ? null : DataConnection.GetDataItem(index);
@@ -1168,14 +1168,14 @@ namespace Avalonia.Controls
}
///
- /// Occurs one time for each public, non-static property in the bound data type when the
- /// property is changed and the
+ /// Occurs one time for each public, non-static property in the bound data type when the
+ /// property is changed and the
/// property is true.
///
public event EventHandler AutoGeneratingColumn;
///
- /// Occurs before a cell or row enters editing mode.
+ /// Occurs before a cell or row enters editing mode.
///
public event EventHandler BeginningEdit;
@@ -1195,7 +1195,7 @@ namespace Avalonia.Controls
public event EventHandler CellPointerPressed;
///
- /// Occurs when the
+ /// Occurs when the
/// property of a column changes.
///
public event EventHandler ColumnDisplayIndexChanged;
@@ -1218,14 +1218,14 @@ namespace Avalonia.Controls
public event EventHandler CurrentCellChanged;
///
- /// Occurs after a
+ /// Occurs after a
/// is instantiated, so that you can customize it before it is used.
///
public event EventHandler LoadingRow;
///
/// Occurs when a cell in a enters editing mode.
- ///
+ ///
///
public event EventHandler PreparingCellForEdit;
@@ -1243,7 +1243,7 @@ namespace Avalonia.Controls
RoutedEvent.Register(nameof(SelectionChanged), RoutingStrategies.Bubble);
///
- /// Occurs when the or
+ /// Occurs when the or
/// property value changes.
///
public event EventHandler SelectionChanged
@@ -1258,19 +1258,19 @@ namespace Avalonia.Controls
public event EventHandler Sorting;
///
- /// Occurs when a
+ /// Occurs when a
/// object becomes available for reuse.
///
public event EventHandler UnloadingRow;
///
- /// Occurs when a new row details template is applied to a row, so that you can customize
+ /// Occurs when a new row details template is applied to a row, so that you can customize
/// the details section before it is used.
///
public event EventHandler LoadingRowDetails;
///
- /// Occurs when the
+ /// Occurs when the
/// property value changes.
///
public event EventHandler RowDetailsVisibilityChanged;
@@ -1282,7 +1282,7 @@ namespace Avalonia.Controls
///
/// Gets a collection that contains all the columns in the control.
- ///
+ ///
public ObservableCollection Columns
{
get
@@ -1456,7 +1456,7 @@ namespace Avalonia.Controls
}
// Height currently available for cells this value is smaller. This height is reduced by the existence of ColumnHeaders
- // or a horizontal scrollbar. Layout is asynchronous so changes to the ColumnHeaders or the horizontal scrollbar are
+ // or a horizontal scrollbar. Layout is asynchronous so changes to the ColumnHeaders or the horizontal scrollbar are
// not reflected immediately.
internal double CellsHeight
{
@@ -1555,7 +1555,7 @@ namespace Avalonia.Controls
internal static double HorizontalGridLinesThickness => DATAGRID_horizontalGridLinesThickness;
- // the sum of the widths in pixels of the scrolling columns preceding
+ // the sum of the widths in pixels of the scrolling columns preceding
// the first displayed scrolling column
internal double HorizontalOffset
{
@@ -2083,20 +2083,20 @@ namespace Avalonia.Controls
}
///
- /// Measures the children of a to prepare for
- /// arranging them during the
- /// pass.
+ /// Measures the children of a to prepare for
+ /// arranging them during the
+ /// pass.
///
///
/// The size that the determines it needs during layout, based on its calculations of child object allocated sizes.
///
///
- /// The available size that this element can give to child elements. Indicates an upper limit that
+ /// The available size that this element can give to child elements. Indicates an upper limit that
/// child elements should not exceed.
///
protected override Size MeasureOverride(Size availableSize)
{
- // Delay layout until after the initial measure to avoid invalid calculations when the
+ // Delay layout until after the initial measure to avoid invalid calculations when the
// DataGrid is not part of the visual tree
if (!_measured)
{
@@ -3006,7 +3006,7 @@ namespace Avalonia.Controls
/// If the editing element has focus, this method will set focus to the DataGrid itself
/// in order to force the element to lose focus. It will then wait for the editing element's
/// LostFocus event, at which point it will perform the specified action.
- ///
+ ///
/// NOTE: It is important to understand that the specified action will be performed when the editing
/// element loses focus only if this method returns true. If it returns false, then the action
/// will not be performed later on, and should instead be performed by the caller, if necessary.
@@ -3065,7 +3065,7 @@ namespace Avalonia.Controls
{
if (!_scrollingByHeight)
{
- // Update layout when RowDetails are expanded or collapsed, just updating the vertical scroll bar is not enough
+ // Update layout when RowDetails are expanded or collapsed, just updating the vertical scroll bar is not enough
// since rows could be added or removed
InvalidateMeasure();
}
@@ -3278,7 +3278,7 @@ namespace Avalonia.Controls
{
// Current cell was reset because the commit deleted row(s).
// Since the user wants to change the current cell, we don't
- // want to end up with no current cell. We pick the last row
+ // want to end up with no current cell. We pick the last row
// in the grid which may be the 'new row'.
int lastSlot = LastVisibleSlot;
if (forCurrentCellChange &&
@@ -3336,7 +3336,7 @@ namespace Avalonia.Controls
if (_ignoreNextScrollBarsLayout)
{
_ignoreNextScrollBarsLayout = false;
- //
+ //
}
@@ -3393,7 +3393,7 @@ namespace Avalonia.Controls
}
// Now cellsWidth is the width potentially available for displaying data cells.
- // Now cellsHeight is the height potentially available for displaying data cells.
+ // Now cellsHeight is the height potentially available for displaying data cells.
bool needHorizScrollbar = false;
bool needVertScrollbar = false;
@@ -3418,7 +3418,7 @@ namespace Avalonia.Controls
Debug.Assert(cellsHeight >= 0);
needHorizScrollbarWithoutVertScrollbar = needHorizScrollbar = true;
- if (vertScrollBarWidth > 0 &&
+ if (vertScrollBarWidth > 0 &&
allowVertScrollbar && (MathUtilities.LessThanOrClose(totalVisibleWidth - cellsWidth, vertScrollBarWidth) ||
MathUtilities.LessThanOrClose(cellsWidth - totalVisibleFrozenWidth, vertScrollBarWidth)))
{
@@ -3458,7 +3458,7 @@ namespace Avalonia.Controls
// we compute the number of visible columns only after we set up the vertical scroll bar.
ComputeDisplayedColumns();
- if ((vertScrollBarWidth > 0 || horizScrollBarHeight > 0) &&
+ if ((vertScrollBarWidth > 0 || horizScrollBarHeight > 0) &&
allowHorizScrollbar &&
needVertScrollbar && !needHorizScrollbar &&
MathUtilities.GreaterThan(totalVisibleWidth, cellsWidth) &&
@@ -3963,7 +3963,8 @@ namespace Avalonia.Controls
{
var errorList =
binding.ValidationErrors
- .SelectMany(ex => ValidationUtil.UnpackException(ex))
+ .SelectMany(ValidationUtil.UnpackException)
+ .Select(ValidationUtil.UnpackDataValidationException)
.ToList();
DataValidationErrors.SetErrors(editingElement, errorList);
@@ -4124,7 +4125,7 @@ namespace Avalonia.Controls
}
///
- /// Exits editing mode without trying to commit or revert the editing, and
+ /// Exits editing mode without trying to commit or revert the editing, and
/// without repopulating the edited row's cell.
///
//TODO TabStop
@@ -5103,9 +5104,9 @@ namespace Avalonia.Controls
{
if (ctrl || _editingColumnIndex == -1 || IsReadOnly)
{
- //Go to the next/previous control on the page when
+ //Go to the next/previous control on the page when
// - Ctrl key is used
- // - Potential current cell is not edited, or the datagrid is read-only.
+ // - Potential current cell is not edited, or the datagrid is read-only.
return false;
}
@@ -5516,11 +5517,11 @@ namespace Avalonia.Controls
// v---v
//|<|_____|###|>|
// ^ ^
- // min max
+ // min max
// we want to make the relative size of the thumb reflect the relative size of the viewing area
// viewportSize / (max + viewportSize) = cellsWidth / max
- // -> viewportSize = max * cellsWidth / (max - cellsWidth)
+ // -> viewportSize = max * cellsWidth / (max - cellsWidth)
// always zero
_hScrollBar.Minimum = 0;
@@ -5572,7 +5573,7 @@ namespace Avalonia.Controls
_hScrollBar.Maximum = 0;
if (_hScrollBar.IsVisible)
{
- // This will trigger a call to this method via Cells_SizeChanged for
+ // This will trigger a call to this method via Cells_SizeChanged for
// which no processing is needed.
_hScrollBar.IsVisible = false;
_ignoreNextScrollBarsLayout = true;
@@ -5591,14 +5592,14 @@ namespace Avalonia.Controls
// v---v
//|<|_____|###|>|
// ^ ^
- // min max
+ // min max
// we want to make the relative size of the thumb reflect the relative size of the viewing area
// viewportSize / (max + viewportSize) = cellsWidth / max
// -> viewportSize = max * cellsHeight / (totalVisibleHeight - cellsHeight)
// -> = max * cellsHeight / (totalVisibleHeight - cellsHeight)
// -> = max * cellsHeight / max
- // -> = cellsHeight
+ // -> = cellsHeight
// always zero
_vScrollBar.Minimum = 0;
@@ -5621,7 +5622,7 @@ namespace Avalonia.Controls
if (!_vScrollBar.IsVisible)
{
- // This will trigger a call to this method via Cells_SizeChanged for
+ // This will trigger a call to this method via Cells_SizeChanged for
// which no processing is needed.
_vScrollBar.IsVisible = true;
if (_vScrollBar.DesiredSize.Width == 0)
@@ -5637,7 +5638,7 @@ namespace Avalonia.Controls
_vScrollBar.Maximum = 0;
if (_vScrollBar.IsVisible)
{
- // This will trigger a call to this method via Cells_SizeChanged for
+ // This will trigger a call to this method via Cells_SizeChanged for
// which no processing is needed.
_vScrollBar.IsVisible = false;
_ignoreNextScrollBarsLayout = true;
@@ -5660,8 +5661,8 @@ namespace Avalonia.Controls
Debug.Assert(slot >= 0);
// Before changing selection, check if the current cell needs to be committed, and
- // check if the current row needs to be committed. If any of those two operations are required and fail,
- // do not change selection, and do not change current cell.
+ // check if the current row needs to be committed. If any of those two operations are required and fail,
+ // do not change selection, and do not change current cell.
bool wasInEdit = EditingColumnIndex != -1;
diff --git a/src/Avalonia.Controls.DataGrid/Utils/ValidationUtil.cs b/src/Avalonia.Controls.DataGrid/Utils/ValidationUtil.cs
index e1ecb2c562..c36d9708c1 100644
--- a/src/Avalonia.Controls.DataGrid/Utils/ValidationUtil.cs
+++ b/src/Avalonia.Controls.DataGrid/Utils/ValidationUtil.cs
@@ -80,19 +80,24 @@ namespace Avalonia.Controls.Utils
{
if (exception != null)
{
- var aggregate = exception as AggregateException;
- var exceptions = aggregate == null ?
- (IEnumerable)new[] { exception } :
- aggregate.InnerExceptions;
- var filtered = exceptions.Where(x => !(x is BindingChainException)).ToList();
+ var exceptions = exception is AggregateException aggregate ?
+ aggregate.InnerExceptions :
+ (IEnumerable)new[] { exception };
- if (filtered.Count > 0)
- {
- return filtered;
- }
+ return exceptions.Where(x => !(x is BindingChainException)).ToList();
}
- return null;
+ return Array.Empty();
+ }
+
+ public static object UnpackDataValidationException(Exception exception)
+ {
+ if (exception is DataValidationException dataValidationException)
+ {
+ return dataValidationException.ErrorData;
+ }
+
+ return exception;
}
///
diff --git a/src/Avalonia.Controls/ContextMenu.cs b/src/Avalonia.Controls/ContextMenu.cs
index 5e17182f3e..fb8080f0d4 100644
--- a/src/Avalonia.Controls/ContextMenu.cs
+++ b/src/Avalonia.Controls/ContextMenu.cs
@@ -246,7 +246,7 @@ namespace Avalonia.Controls
///
/// Opens the menu.
///
- public override void Open() => throw new NotSupportedException();
+ public override void Open() => Open(null);
///
/// Opens a context menu on the specified control.
diff --git a/src/Avalonia.Layout/ElementManager.cs b/src/Avalonia.Layout/ElementManager.cs
index 70805ba31c..bf5a45966b 100644
--- a/src/Avalonia.Layout/ElementManager.cs
+++ b/src/Avalonia.Layout/ElementManager.cs
@@ -129,7 +129,7 @@ namespace Avalonia.Layout
{
for (int i = 0; i < count; i++)
{
- // Clear from the edges so that ItemsRepeater can optimize on maintaining
+ // Clear from the edges so that ItemsRepeater can optimize on maintaining
// realized indices without walking through all the children every time.
int index = realizedIndex == 0 ? realizedIndex + i : (realizedIndex + count - 1) - i;
var elementRef = _realizedElements[index];
@@ -212,7 +212,7 @@ namespace Avalonia.Layout
public ILayoutable GetRealizedElement(int dataIndex)
{
return IsVirtualizingContext ?
- GetAt(GetRealizedRangeIndexFromDataIndex(dataIndex)) :
+ GetAt(GetRealizedRangeIndexFromDataIndex(dataIndex)) :
_context.GetOrCreateElementAt(
dataIndex,
ElementRealizationOptions.ForceCreate | ElementRealizationOptions.SuppressAutoRecycle);
@@ -252,7 +252,6 @@ namespace Avalonia.Layout
(orientation == ScrollOrientation.Vertical ? ScrollOrientation.Horizontal : ScrollOrientation.Vertical) :
orientation;
-
var windowStart = effectiveOrientation == ScrollOrientation.Vertical ? window.Y : window.X;
var windowEnd = effectiveOrientation == ScrollOrientation.Vertical ? window.Y + window.Height : window.X + window.Width;
var firstElementStart = effectiveOrientation == ScrollOrientation.Vertical ? firstElementBounds.Y : firstElementBounds.X;
@@ -273,53 +272,53 @@ namespace Avalonia.Layout
switch (args.Action)
{
case NotifyCollectionChangedAction.Add:
- {
- OnItemsAdded(args.NewStartingIndex, args.NewItems.Count);
- }
- break;
+ {
+ OnItemsAdded(args.NewStartingIndex, args.NewItems.Count);
+ }
+ break;
case NotifyCollectionChangedAction.Replace:
- {
- int oldSize = args.OldItems.Count;
- int newSize = args.NewItems.Count;
- int oldStartIndex = args.OldStartingIndex;
- int newStartIndex = args.NewStartingIndex;
-
- if (oldSize == newSize &&
- oldStartIndex == newStartIndex &&
- IsDataIndexRealized(oldStartIndex) &&
- IsDataIndexRealized(oldStartIndex + oldSize -1))
{
- // Straight up replace of n items within the realization window.
- // Removing and adding might causes us to lose the anchor causing us
- // to throw away all containers and start from scratch.
- // Instead, we can just clear those items and set the element to
- // null (sentinel) and let the next measure get new containers for them.
- var startRealizedIndex = GetRealizedRangeIndexFromDataIndex(oldStartIndex);
- for (int realizedIndex = startRealizedIndex; realizedIndex < startRealizedIndex + oldSize; realizedIndex++)
+ int oldSize = args.OldItems.Count;
+ int newSize = args.NewItems.Count;
+ int oldStartIndex = args.OldStartingIndex;
+ int newStartIndex = args.NewStartingIndex;
+
+ if (oldSize == newSize &&
+ oldStartIndex == newStartIndex &&
+ IsDataIndexRealized(oldStartIndex) &&
+ IsDataIndexRealized(oldStartIndex + oldSize - 1))
{
- var elementRef = _realizedElements[realizedIndex];
-
- if (elementRef != null)
+ // Straight up replace of n items within the realization window.
+ // Removing and adding might causes us to lose the anchor causing us
+ // to throw away all containers and start from scratch.
+ // Instead, we can just clear those items and set the element to
+ // null (sentinel) and let the next measure get new containers for them.
+ var startRealizedIndex = GetRealizedRangeIndexFromDataIndex(oldStartIndex);
+ for (int realizedIndex = startRealizedIndex; realizedIndex < startRealizedIndex + oldSize; realizedIndex++)
{
- _context.RecycleElement(elementRef);
- _realizedElements[realizedIndex] = null;
+ var elementRef = _realizedElements[realizedIndex];
+
+ if (elementRef != null)
+ {
+ _context.RecycleElement(elementRef);
+ _realizedElements[realizedIndex] = null;
+ }
}
}
+ else
+ {
+ OnItemsRemoved(oldStartIndex, oldSize);
+ OnItemsAdded(newStartIndex, newSize);
+ }
}
- else
- {
- OnItemsRemoved(oldStartIndex, oldSize);
- OnItemsAdded(newStartIndex, newSize);
- }
- }
- break;
+ break;
case NotifyCollectionChangedAction.Remove:
- {
- OnItemsRemoved(args.OldStartingIndex, args.OldItems.Count);
- }
- break;
+ {
+ OnItemsRemoved(args.OldStartingIndex, args.OldItems.Count);
+ }
+ break;
case NotifyCollectionChangedAction.Reset:
ClearRealizedRange();
@@ -376,7 +375,7 @@ namespace Avalonia.Layout
int backCutoffIndex = realizedRangeSize;
for (int i = 0;
- i _firstRealizedDataIndex &&
+ if (newStartingIndex >= _firstRealizedDataIndex &&
newStartingIndex <= lastRealizedDataIndex)
{
// Inserted within the realized range
int insertRangeStartIndex = newStartingIndex - _firstRealizedDataIndex;
for (int i = 0; i < count; i++)
{
- // Insert null (sentinel) here instead of an element, that way we dont
+ // Insert null (sentinel) here instead of an element, that way we dont
// end up creating a lot of elements only to be thrown out in the next layout.
int insertRangeIndex = insertRangeStartIndex + i;
int dataIndex = newStartingIndex + i;
diff --git a/src/Avalonia.Themes.Fluent/Controls/Expander.xaml b/src/Avalonia.Themes.Fluent/Controls/Expander.xaml
index 97ca62c493..ad0fd18ea5 100644
--- a/src/Avalonia.Themes.Fluent/Controls/Expander.xaml
+++ b/src/Avalonia.Themes.Fluent/Controls/Expander.xaml
@@ -108,7 +108,7 @@