Fix a bunch of templating issues

This commit is contained in:
TheXamlGuy
2024-07-17 20:43:39 +01:00
parent 60b784aa25
commit efd00ff81a
11 changed files with 315 additions and 116 deletions
+1 -1
View File
@@ -5,7 +5,7 @@
<Nullable>enable</Nullable> <Nullable>enable</Nullable>
</PropertyGroup> </PropertyGroup>
<ItemGroup> <ItemGroup>
<PackageReference Include="Avalonia" Version="11.1.0-rc1" /> <PackageReference Include="Avalonia" Version="11.1.0-rc2" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<ProjectReference Include="..\Toolkit.Foundation\Toolkit.Foundation.csproj" /> <ProjectReference Include="..\Toolkit.Foundation\Toolkit.Foundation.csproj" />
+1 -1
View File
@@ -9,7 +9,7 @@
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<PackageReference Include="CommunityToolkit.Mvvm" Version="8.2.2" /> <PackageReference Include="CommunityToolkit.Mvvm" Version="8.2.2" />
<PackageReference Include="Microsoft.Extensions.Hosting" Version="9.0.0-preview.5.24306.7" /> <PackageReference Include="Microsoft.Extensions.Hosting" Version="9.0.0-preview.6.24327.7" />
<PackageReference Include="System.Reactive" Version="6.0.1" /> <PackageReference Include="System.Reactive" Version="6.0.1" />
</ItemGroup> </ItemGroup>
</Project> </Project>
@@ -5,8 +5,8 @@
<Nullable>enable</Nullable> <Nullable>enable</Nullable>
</PropertyGroup> </PropertyGroup>
<ItemGroup> <ItemGroup>
<PackageReference Include="Avalonia" Version="11.1.0-rc1" /> <PackageReference Include="Avalonia" Version="11.1.0-rc2" />
<PackageReference Include="Avalonia.Xaml.Behaviors" Version="11.1.0-rc1" /> <PackageReference Include="Avalonia.Xaml.Behaviors" Version="11.1.0-rc2" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<ProjectReference Include="..\Toolkit.Foundation\Toolkit.Foundation.csproj" /> <ProjectReference Include="..\Toolkit.Foundation\Toolkit.Foundation.csproj" />
@@ -8,106 +8,138 @@ namespace Toolkit.UI.Controls.Avalonia;
public class ContentBadge : public class ContentBadge :
ContentControl ContentControl
{ {
public static readonly StyledProperty<string?> BadgePathProperty = public static readonly StyledProperty<string> BadgePathProperty =
AvaloniaProperty.Register<ContentBadge, string?>(nameof(BadgePath)); AvaloniaProperty.Register<ContentBadge, string>(nameof(BadgePath));
public static readonly StyledProperty<double> BadgeSizeProperty =
AvaloniaProperty.Register<ContentBadge, double>(nameof(BadgeSize), 14);
public static readonly StyledProperty<ContentBadgePlacement> BadgePlacementProperty = public static readonly StyledProperty<ContentBadgePlacement> BadgePlacementProperty =
AvaloniaProperty.Register<ContentBadge, ContentBadgePlacement>(nameof(BadgePlacement), ContentBadgePlacement.BottomRight); AvaloniaProperty.Register<ContentBadge, ContentBadgePlacement>(nameof(BadgePlacement), ContentBadgePlacement.BottomRight);
public static readonly StyledProperty<double> BadgeSizeProperty =
AvaloniaProperty.Register<ContentBadge, double>(nameof(BadgeSize), 14);
public static readonly StyledProperty<bool> IsBadgeVisibleProperty =
AvaloniaProperty.Register<ContentBadge, bool>(nameof(IsBadgeVisible), true);
protected override void OnPropertyChanged(AvaloniaPropertyChangedEventArgs change)
{
base.OnPropertyChanged(change);
if (change.Property == BadgePathProperty ||
change.Property == BadgeSizeProperty ||
change.Property == IsBadgeVisibleProperty)
{
UpdateBadge();
}
}
private ContentControl? badgeContent; private ContentControl? badgeContent;
public string BadgePath
{
get => GetValue(BadgePathProperty);
set => SetValue(BadgePathProperty, value);
}
public ContentBadgePlacement BadgePlacement public ContentBadgePlacement BadgePlacement
{ {
get => GetValue(BadgePlacementProperty); get => GetValue(BadgePlacementProperty);
set => SetValue(BadgePlacementProperty, value); set => SetValue(BadgePlacementProperty, value);
} }
public string? BadgePath
{
get => GetValue(BadgePathProperty);
set => SetValue(BadgePathProperty, value);
}
public double BadgeSize public double BadgeSize
{ {
get => GetValue(BadgeSizeProperty); get => GetValue(BadgeSizeProperty);
set => SetValue(BadgeSizeProperty, value); set => SetValue(BadgeSizeProperty, value);
} }
public void UpdateClip() public bool IsBadgeVisible
{ {
if (Content is Control content && get => GetValue(IsBadgeVisibleProperty);
badgeContent is not null && set => SetValue(IsBadgeVisibleProperty, value);
BadgePath is { Length: > 0 } && }
Geometry.Parse(BadgePath) is Geometry geometry)
public void UpdateBadge()
{
if (Content is Control content && badgeContent is not null)
{ {
double backgroundWidth = DesiredSize.Width; if (IsBadgeVisible &&
double backgroundHeight = DesiredSize.Height; BadgePath is { Length: > 0 } &&
Geometry.Parse(BadgePath) is Geometry geometry)
double scaleX = BadgeSize / geometry.Bounds.Width;
double scaleY = BadgeSize / geometry.Bounds.Height;
double adjustedStrokeWidth = Math.Min(scaleX, scaleY) * 8;
Geometry knockoutGeometry = geometry.GetWidenedGeometry(new Pen(new SolidColorBrush(Colors.Transparent), adjustedStrokeWidth));
TransformGroup transformGroup = new();
transformGroup.Children.Add(new ScaleTransform(scaleX, scaleY));
double scaledWidth = knockoutGeometry.Bounds.Width * scaleX;
double scaledHeight = knockoutGeometry.Bounds.Height * scaleY;
double offsetX = 0;
double offsetY = 0;
switch (BadgePlacement)
{ {
case ContentBadgePlacement.TopLeft: double backgroundWidth = DesiredSize.Width;
offsetX = 0; double backgroundHeight = DesiredSize.Height;
offsetY = 0;
break; double badgeWidth = geometry.Bounds.Width;
case ContentBadgePlacement.TopRight: double badgeHeight = geometry.Bounds.Height;
offsetX = backgroundWidth - scaledWidth; double scale = BadgeSize / Math.Max(badgeWidth, badgeHeight);
offsetY = 0;
break; double scaleX = scale;
case ContentBadgePlacement.BottomLeft: double scaleY = scale;
offsetX = 0;
offsetY = backgroundHeight - scaledHeight; double adjustedStrokeWidth = Math.Min(scaleX, scaleY) * 8;
break;
case ContentBadgePlacement.BottomRight: Geometry knockoutGeometry = geometry.GetWidenedGeometry(new Pen(new SolidColorBrush(Colors.Transparent), adjustedStrokeWidth));
offsetX = backgroundWidth - scaledWidth;
offsetY = backgroundHeight - scaledHeight; TransformGroup transformGroup = new();
break; transformGroup.Children.Add(new ScaleTransform(scaleX, scaleY));
double scaledWidth = knockoutGeometry.Bounds.Width * scaleX;
double scaledHeight = knockoutGeometry.Bounds.Height * scaleY;
double offsetX = 0;
double offsetY = 0;
switch (BadgePlacement)
{
case ContentBadgePlacement.TopLeft:
offsetX = 0;
offsetY = 0;
break;
case ContentBadgePlacement.TopRight:
offsetX = backgroundWidth - scaledWidth;
offsetY = 0;
break;
case ContentBadgePlacement.BottomLeft:
offsetX = 0;
offsetY = backgroundHeight - scaledHeight;
break;
case ContentBadgePlacement.BottomRight:
offsetX = backgroundWidth - scaledWidth;
offsetY = backgroundHeight - scaledHeight;
break;
}
transformGroup.Children.Add(new TranslateTransform(offsetX, offsetY));
knockoutGeometry.Transform = transformGroup;
CombinedGeometry combinedGeometry = new()
{
GeometryCombineMode = GeometryCombineMode.Exclude,
Geometry1 = new RectangleGeometry { Rect = new Rect(0, 0, backgroundWidth, backgroundHeight) },
Geometry2 = knockoutGeometry
};
content.Clip = combinedGeometry;
Geometry overlayGeometry = geometry.Clone();
TransformGroup overlayTransformGroup = new();
overlayTransformGroup.Children.Add(new ScaleTransform(scaleX, scaleY));
overlayTransformGroup.Children.Add(new TranslateTransform(offsetX, offsetY));
overlayGeometry.Transform = overlayTransformGroup;
badgeContent.Content = new Path
{
Data = overlayGeometry,
Fill = Foreground
};
} }
else
transformGroup.Children.Add(new TranslateTransform(offsetX, offsetY));
knockoutGeometry.Transform = transformGroup;
CombinedGeometry combinedGeometry = new()
{ {
GeometryCombineMode = GeometryCombineMode.Exclude, badgeContent.Content = null;
Geometry1 = new RectangleGeometry { Rect = new Rect(0, 0, backgroundWidth, backgroundHeight) }, content.Clip = null;
Geometry2 = knockoutGeometry }
};
content.Clip = combinedGeometry;
Geometry overlayGeometry = geometry.Clone();
TransformGroup overlayTransformGroup = new();
overlayTransformGroup.Children.Add(new ScaleTransform(scaleX, scaleY));
overlayTransformGroup.Children.Add(new TranslateTransform(offsetX, offsetY));
overlayGeometry.Transform = overlayTransformGroup;
badgeContent.Content = new Path
{
Data = overlayGeometry,
Fill = Foreground
};
} }
} }
@@ -120,7 +152,7 @@ public class ContentBadge :
protected override void OnSizeChanged(SizeChangedEventArgs args) protected override void OnSizeChanged(SizeChangedEventArgs args)
{ {
base.OnSizeChanged(args); base.OnSizeChanged(args);
UpdateClip(); UpdateBadge();
} }
} }
@@ -13,7 +13,44 @@
<x:Double x:Key="OverflowItemSpacing">6</x:Double> <x:Double x:Key="OverflowItemSpacing">6</x:Double>
<x:Double x:Key="OverflowItemSize">40</x:Double> <x:Double x:Key="OverflowItemSize">40</x:Double>
<CornerRadius x:Key="OverflowItemCornerRadius">40</CornerRadius> <CornerRadius x:Key="OverflowItemCornerRadius">40</CornerRadius>
<ControlTheme x:Key="OverflowItemStyle" TargetType="ListBoxItem"> <ControlTheme x:Key="{x:Type OverflowList}" TargetType="OverflowList">
<Setter Property="Foreground" Value="{DynamicResource ListBoxForeground}" />
<Setter Property="Background" Value="{DynamicResource ListBoxBackground}" />
<Setter Property="BorderBrush" Value="{DynamicResource ListBoxBorder}" />
<Setter Property="BorderThickness" Value="{DynamicResource ListBoxBorderThemeThickness}" />
<Setter Property="ScrollViewer.HorizontalScrollBarVisibility" Value="Disabled" />
<Setter Property="ScrollViewer.VerticalScrollBarVisibility" Value="Auto" />
<Setter Property="ScrollViewer.IsScrollChainingEnabled" Value="True" />
<Setter Property="ScrollViewer.IsScrollInertiaEnabled" Value="True" />
<Setter Property="FontSize" Value="{DynamicResource ControlContentThemeFontSize}" />
<Setter Property="Template">
<ControlTemplate>
<Border
Name="border"
BorderBrush="{TemplateBinding BorderBrush}"
BorderThickness="{TemplateBinding BorderThickness}">
<ScrollViewer
Name="PART_ScrollViewer"
AllowAutoHide="{TemplateBinding (ScrollViewer.AllowAutoHide)}"
Background="{TemplateBinding Background}"
BringIntoViewOnFocusChange="{TemplateBinding (ScrollViewer.BringIntoViewOnFocusChange)}"
HorizontalScrollBarVisibility="{TemplateBinding (ScrollViewer.HorizontalScrollBarVisibility)}"
HorizontalSnapPointsType="{TemplateBinding (ScrollViewer.HorizontalSnapPointsType)}"
IsDeferredScrollingEnabled="{TemplateBinding (ScrollViewer.IsDeferredScrollingEnabled)}"
IsScrollChainingEnabled="{TemplateBinding (ScrollViewer.IsScrollChainingEnabled)}"
IsScrollInertiaEnabled="{TemplateBinding (ScrollViewer.IsScrollInertiaEnabled)}"
VerticalScrollBarVisibility="{TemplateBinding (ScrollViewer.VerticalScrollBarVisibility)}"
VerticalSnapPointsType="{TemplateBinding (ScrollViewer.VerticalSnapPointsType)}">
<ItemsPresenter
Name="PART_ItemsPresenter"
Margin="{TemplateBinding Padding}"
ItemsPanel="{TemplateBinding ItemsPanel}" />
</ScrollViewer>
</Border>
</ControlTemplate>
</Setter>
</ControlTheme>
<ControlTheme x:Key="{x:Type controls:OverflowItem}" TargetType="controls:OverflowItem">
<Setter Property="FontFamily" Value="{DynamicResource ContentControlThemeFontFamily}" /> <Setter Property="FontFamily" Value="{DynamicResource ContentControlThemeFontFamily}" />
<Setter Property="FontSize" Value="{DynamicResource ControlContentThemeFontSize}" /> <Setter Property="FontSize" Value="{DynamicResource ControlContentThemeFontSize}" />
<Setter Property="Background" Value="{DynamicResource ListViewItemBackground}" /> <Setter Property="Background" Value="{DynamicResource ListViewItemBackground}" />
@@ -34,21 +71,28 @@
BorderBrush="{TemplateBinding BorderBrush}" BorderBrush="{TemplateBinding BorderBrush}"
BorderThickness="{TemplateBinding BorderThickness}" BorderThickness="{TemplateBinding BorderThickness}"
CornerRadius="{TemplateBinding CornerRadius}"> CornerRadius="{TemplateBinding CornerRadius}">
<Grid> <controls:ContentBadge
<ContentPresenter BadgePath="{TemplateBinding BadgePath}"
Name="PART_ContentPresenter" BadgePlacement="{TemplateBinding BadgePlacement}"
HorizontalContentAlignment="{TemplateBinding HorizontalContentAlignment}" BadgeSize="{TemplateBinding BadgeSize}"
VerticalContentAlignment="{TemplateBinding VerticalContentAlignment}" Foreground="Red"
Content="{TemplateBinding Content}" IsBadgeVisible="{TemplateBinding IsBadgeVisible}">
ContentTemplate="{TemplateBinding ContentTemplate}" /> <Grid>
<Border <ContentPresenter
Name="SelectionIndicator" Name="PART_ContentPresenter"
BorderBrush="{DynamicResource AccentFillColorDefaultBrush}" HorizontalContentAlignment="{TemplateBinding HorizontalContentAlignment}"
BorderThickness="3" VerticalContentAlignment="{TemplateBinding VerticalContentAlignment}"
CornerRadius="{TemplateBinding CornerRadius}" Content="{TemplateBinding Content}"
IsVisible="False" />
UseLayoutRounding="False" /> <Border
</Grid> Name="SelectionIndicator"
BorderBrush="{DynamicResource AccentFillColorDefaultBrush}"
BorderThickness="3"
CornerRadius="{TemplateBinding CornerRadius}"
IsVisible="False"
UseLayoutRounding="False" />
</Grid>
</controls:ContentBadge>
</Border> </Border>
</Panel> </Panel>
</ControlTemplate> </ControlTemplate>
@@ -116,18 +160,17 @@
<Setter Property="Template"> <Setter Property="Template">
<ControlTemplate> <ControlTemplate>
<StackPanel Margin="{TemplateBinding Margin}"> <StackPanel Margin="{TemplateBinding Margin}">
<ListBox <controls:OverflowList
x:Name="PrimaryListBox" x:Name="PrimaryListBox"
Grid.Column="0" Grid.Column="0"
ItemContainerTheme="{StaticResource OverflowItemStyle}"
ItemTemplate="{TemplateBinding ItemTemplate}" ItemTemplate="{TemplateBinding ItemTemplate}"
SelectedItem="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=TemplateSettings.PrimarySelection, Mode=TwoWay}"> SelectedItem="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=TemplateSettings.PrimarySelection, Mode=TwoWay}">
<ListBox.ItemsPanel> <controls:OverflowList.ItemsPanel>
<ItemsPanelTemplate> <ItemsPanelTemplate>
<StackPanel Orientation="Horizontal" Spacing="{StaticResource OverflowItemSpacing}" /> <StackPanel Orientation="Horizontal" Spacing="{StaticResource OverflowItemSpacing}" />
</ItemsPanelTemplate> </ItemsPanelTemplate>
</ListBox.ItemsPanel> </controls:OverflowList.ItemsPanel>
</ListBox> </controls:OverflowList>
<Grid <Grid
x:Name="Spacer" x:Name="Spacer"
Grid.Column="1" Grid.Column="1"
@@ -153,17 +196,16 @@
</Viewbox> </Viewbox>
<Button.Flyout> <Button.Flyout>
<Flyout> <Flyout>
<ListBox <controls:OverflowList
x:Name="SecondaryListBox" x:Name="SecondaryListBox"
ItemContainerTheme="{StaticResource OverflowItemStyle}"
ItemTemplate="{TemplateBinding ItemTemplate}" ItemTemplate="{TemplateBinding ItemTemplate}"
SelectedItem="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=TemplateSettings.SecondarySelection, Mode=TwoWay}"> SelectedItem="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=TemplateSettings.SecondarySelection, Mode=TwoWay}">
<ListBox.ItemsPanel> <controls:OverflowList.ItemsPanel>
<ItemsPanelTemplate> <ItemsPanelTemplate>
<StackPanel Orientation="Horizontal" Spacing="{StaticResource OverflowItemSpacing}" /> <StackPanel Orientation="Horizontal" Spacing="{StaticResource OverflowItemSpacing}" />
</ItemsPanelTemplate> </ItemsPanelTemplate>
</ListBox.ItemsPanel> </controls:OverflowList.ItemsPanel>
</ListBox> </controls:OverflowList>
</Flyout> </Flyout>
</Button.Flyout> </Button.Flyout>
</Button> </Button>
@@ -29,13 +29,14 @@ public class Overflow :
private static readonly StyledProperty<OverflowTemplateSettings> TemplateSettingsProperty = private static readonly StyledProperty<OverflowTemplateSettings> TemplateSettingsProperty =
AvaloniaProperty.Register<Overflow, OverflowTemplateSettings>(nameof(TemplateSettings)); AvaloniaProperty.Register<Overflow, OverflowTemplateSettings>(nameof(TemplateSettings));
private readonly ObservableCollection<object> primaryCollection = []; private readonly ObservableCollection<object> primaryCollection = [];
private readonly ObservableCollection<object> secondaryCollection = []; private readonly ObservableCollection<object> secondaryCollection = [];
private ListBox? primaryListBox; private OverflowList? primaryListBox;
private ListBox? secondaryListBox; private OverflowList? secondaryListBox;
public Overflow() public Overflow()
{ {
@@ -59,7 +60,6 @@ public class Overflow :
get => GetValue(ItemsSourceProperty); get => GetValue(ItemsSourceProperty);
set => SetValue(ItemsSourceProperty, value); set => SetValue(ItemsSourceProperty, value);
} }
[InheritDataTypeFromItems(nameof(ItemsSource))] [InheritDataTypeFromItems(nameof(ItemsSource))]
public IDataTemplate? ItemTemplate public IDataTemplate? ItemTemplate
{ {
@@ -83,10 +83,10 @@ public class Overflow :
{ {
base.OnApplyTemplate(args); base.OnApplyTemplate(args);
primaryListBox = args.NameScope.Get<ListBox>("PrimaryListBox"); primaryListBox = args.NameScope.Get<OverflowList>("PrimaryListBox");
primaryListBox?.SetValue(ItemsControl.ItemsSourceProperty, primaryCollection); primaryListBox?.SetValue(ItemsControl.ItemsSourceProperty, primaryCollection);
secondaryListBox = args.NameScope.Get<ListBox>("SecondaryListBox"); secondaryListBox = args.NameScope.Get<OverflowList>("SecondaryListBox");
secondaryListBox?.SetValue(ItemsControl.ItemsSourceProperty, secondaryCollection); secondaryListBox?.SetValue(ItemsControl.ItemsSourceProperty, secondaryCollection);
InitializeCollections(); InitializeCollections();
@@ -0,0 +1,45 @@
using Avalonia;
using Avalonia.Controls;
namespace Toolkit.UI.Controls.Avalonia;
public class OverflowItem :
ListBoxItem
{
public static readonly StyledProperty<double> BadgeSizeProperty =
AvaloniaProperty.Register<OverflowItem, double>(nameof(BadgeSize), 14);
public static readonly StyledProperty<bool> IsBadgeVisibleProperty =
AvaloniaProperty.Register<OverflowItem, bool>(nameof(IsBadgeVisible), true);
public static readonly StyledProperty<string> BadgePathProperty =
AvaloniaProperty.Register<OverflowItem, string>(nameof(BadgePath));
public static readonly StyledProperty<ContentBadgePlacement> BadgePlacementProperty =
AvaloniaProperty.Register<OverflowItem, ContentBadgePlacement>(nameof(BadgePlacement), ContentBadgePlacement.BottomRight);
public string BadgePath
{
get => GetValue(BadgePathProperty);
set => SetValue(BadgePathProperty, value);
}
public ContentBadgePlacement BadgePlacement
{
get => GetValue(BadgePlacementProperty);
set => SetValue(BadgePlacementProperty, value);
}
public double BadgeSize
{
get => GetValue(BadgeSizeProperty);
set => SetValue(BadgeSizeProperty, value);
}
public bool IsBadgeVisible
{
get => GetValue(IsBadgeVisibleProperty);
set => SetValue(IsBadgeVisibleProperty, value);
}
}
@@ -0,0 +1,39 @@
using Avalonia.Controls;
using Avalonia.Controls.Templates;
namespace Toolkit.UI.Controls.Avalonia;
public class OverflowList :
ListBox
{
protected override Control CreateContainerForItemOverride(object? item, int index, object? recycleKey)
{
if (recycleKey is IDataTemplate itemContainerTemplate)
{
if (itemContainerTemplate.Build(item) is OverflowItem container)
{
return container;
}
}
return new OverflowItem();
}
protected override bool NeedsContainerOverride(object? item, int index, out object? recycleKey)
{
if (item is OverflowItem)
{
recycleKey = null;
return false;
}
if (this.FindDataTemplate(item, ItemTemplate) is IDataTemplate itemContainerTemplate)
{
recycleKey = itemContainerTemplate;
return true;
}
recycleKey = DefaultRecycleKey;
return true;
}
}
@@ -0,0 +1,43 @@
using Avalonia.Controls;
using Avalonia.Controls.Templates;
namespace Toolkit.UI.Controls.Avalonia;
public class TemplateListBox :
ListBox
{
protected override Type StyleKeyOverride =>
typeof(ListBox);
protected override Control CreateContainerForItemOverride(object? item, int index, object? recycleKey)
{
if (recycleKey is IDataTemplate itemContainerTemplate)
{
if (itemContainerTemplate.Build(item) is ListBoxItem container)
{
return container;
}
}
return new ListBoxItem();
}
protected override bool NeedsContainerOverride(object? item, int index, out object? recycleKey)
{
if (item is ListBoxItem)
{
recycleKey = null;
return false;
}
if (this.FindDataTemplate(item, ItemTemplate) is IDataTemplate itemContainerTemplate)
{
recycleKey = itemContainerTemplate;
return true;
}
recycleKey = DefaultRecycleKey;
return true;
}
}
@@ -1,6 +1,4 @@
using Avalonia; using Avalonia;
using Avalonia.Controls;
using Avalonia.Controls.Primitives;
using Avalonia.Controls.Templates; using Avalonia.Controls.Templates;
namespace Toolkit.UI.Controls.Avalonia; namespace Toolkit.UI.Controls.Avalonia;
@@ -12,7 +12,7 @@
<AvaloniaResource Include="Fonts\FluentSystemIcons-Resizable.ttf" /> <AvaloniaResource Include="Fonts\FluentSystemIcons-Resizable.ttf" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<PackageReference Include="Avalonia" Version="11.1.0-rc1" /> <PackageReference Include="Avalonia" Version="11.1.0-rc2" />
<PackageReference Include="Avalonia.Labs.Controls" Version="11.0.10.1" /> <PackageReference Include="Avalonia.Labs.Controls" Version="11.0.10.1" />
<PackageReference Include="FluentAvaloniaUI" Version="2.1.0-preview6" /> <PackageReference Include="FluentAvaloniaUI" Version="2.1.0-preview6" />
</ItemGroup> </ItemGroup>