Fix a bunch of templating issues
This commit is contained in:
@@ -13,7 +13,44 @@
|
||||
<x:Double x:Key="OverflowItemSpacing">6</x:Double>
|
||||
<x:Double x:Key="OverflowItemSize">40</x:Double>
|
||||
<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="FontSize" Value="{DynamicResource ControlContentThemeFontSize}" />
|
||||
<Setter Property="Background" Value="{DynamicResource ListViewItemBackground}" />
|
||||
@@ -34,21 +71,28 @@
|
||||
BorderBrush="{TemplateBinding BorderBrush}"
|
||||
BorderThickness="{TemplateBinding BorderThickness}"
|
||||
CornerRadius="{TemplateBinding CornerRadius}">
|
||||
<Grid>
|
||||
<ContentPresenter
|
||||
Name="PART_ContentPresenter"
|
||||
HorizontalContentAlignment="{TemplateBinding HorizontalContentAlignment}"
|
||||
VerticalContentAlignment="{TemplateBinding VerticalContentAlignment}"
|
||||
Content="{TemplateBinding Content}"
|
||||
ContentTemplate="{TemplateBinding ContentTemplate}" />
|
||||
<Border
|
||||
Name="SelectionIndicator"
|
||||
BorderBrush="{DynamicResource AccentFillColorDefaultBrush}"
|
||||
BorderThickness="3"
|
||||
CornerRadius="{TemplateBinding CornerRadius}"
|
||||
IsVisible="False"
|
||||
UseLayoutRounding="False" />
|
||||
</Grid>
|
||||
<controls:ContentBadge
|
||||
BadgePath="{TemplateBinding BadgePath}"
|
||||
BadgePlacement="{TemplateBinding BadgePlacement}"
|
||||
BadgeSize="{TemplateBinding BadgeSize}"
|
||||
Foreground="Red"
|
||||
IsBadgeVisible="{TemplateBinding IsBadgeVisible}">
|
||||
<Grid>
|
||||
<ContentPresenter
|
||||
Name="PART_ContentPresenter"
|
||||
HorizontalContentAlignment="{TemplateBinding HorizontalContentAlignment}"
|
||||
VerticalContentAlignment="{TemplateBinding VerticalContentAlignment}"
|
||||
Content="{TemplateBinding Content}"
|
||||
/>
|
||||
<Border
|
||||
Name="SelectionIndicator"
|
||||
BorderBrush="{DynamicResource AccentFillColorDefaultBrush}"
|
||||
BorderThickness="3"
|
||||
CornerRadius="{TemplateBinding CornerRadius}"
|
||||
IsVisible="False"
|
||||
UseLayoutRounding="False" />
|
||||
</Grid>
|
||||
</controls:ContentBadge>
|
||||
</Border>
|
||||
</Panel>
|
||||
</ControlTemplate>
|
||||
@@ -116,18 +160,17 @@
|
||||
<Setter Property="Template">
|
||||
<ControlTemplate>
|
||||
<StackPanel Margin="{TemplateBinding Margin}">
|
||||
<ListBox
|
||||
<controls:OverflowList
|
||||
x:Name="PrimaryListBox"
|
||||
Grid.Column="0"
|
||||
ItemContainerTheme="{StaticResource OverflowItemStyle}"
|
||||
ItemTemplate="{TemplateBinding ItemTemplate}"
|
||||
SelectedItem="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=TemplateSettings.PrimarySelection, Mode=TwoWay}">
|
||||
<ListBox.ItemsPanel>
|
||||
<controls:OverflowList.ItemsPanel>
|
||||
<ItemsPanelTemplate>
|
||||
<StackPanel Orientation="Horizontal" Spacing="{StaticResource OverflowItemSpacing}" />
|
||||
</ItemsPanelTemplate>
|
||||
</ListBox.ItemsPanel>
|
||||
</ListBox>
|
||||
</controls:OverflowList.ItemsPanel>
|
||||
</controls:OverflowList>
|
||||
<Grid
|
||||
x:Name="Spacer"
|
||||
Grid.Column="1"
|
||||
@@ -153,17 +196,16 @@
|
||||
</Viewbox>
|
||||
<Button.Flyout>
|
||||
<Flyout>
|
||||
<ListBox
|
||||
<controls:OverflowList
|
||||
x:Name="SecondaryListBox"
|
||||
ItemContainerTheme="{StaticResource OverflowItemStyle}"
|
||||
ItemTemplate="{TemplateBinding ItemTemplate}"
|
||||
SelectedItem="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=TemplateSettings.SecondarySelection, Mode=TwoWay}">
|
||||
<ListBox.ItemsPanel>
|
||||
<controls:OverflowList.ItemsPanel>
|
||||
<ItemsPanelTemplate>
|
||||
<StackPanel Orientation="Horizontal" Spacing="{StaticResource OverflowItemSpacing}" />
|
||||
</ItemsPanelTemplate>
|
||||
</ListBox.ItemsPanel>
|
||||
</ListBox>
|
||||
</controls:OverflowList.ItemsPanel>
|
||||
</controls:OverflowList>
|
||||
</Flyout>
|
||||
</Button.Flyout>
|
||||
</Button>
|
||||
|
||||
@@ -29,13 +29,14 @@ public class Overflow :
|
||||
private static readonly StyledProperty<OverflowTemplateSettings> TemplateSettingsProperty =
|
||||
AvaloniaProperty.Register<Overflow, OverflowTemplateSettings>(nameof(TemplateSettings));
|
||||
|
||||
|
||||
private readonly ObservableCollection<object> primaryCollection = [];
|
||||
|
||||
private readonly ObservableCollection<object> secondaryCollection = [];
|
||||
|
||||
private ListBox? primaryListBox;
|
||||
private OverflowList? primaryListBox;
|
||||
|
||||
private ListBox? secondaryListBox;
|
||||
private OverflowList? secondaryListBox;
|
||||
|
||||
public Overflow()
|
||||
{
|
||||
@@ -59,7 +60,6 @@ public class Overflow :
|
||||
get => GetValue(ItemsSourceProperty);
|
||||
set => SetValue(ItemsSourceProperty, value);
|
||||
}
|
||||
|
||||
[InheritDataTypeFromItems(nameof(ItemsSource))]
|
||||
public IDataTemplate? ItemTemplate
|
||||
{
|
||||
@@ -83,10 +83,10 @@ public class Overflow :
|
||||
{
|
||||
base.OnApplyTemplate(args);
|
||||
|
||||
primaryListBox = args.NameScope.Get<ListBox>("PrimaryListBox");
|
||||
primaryListBox = args.NameScope.Get<OverflowList>("PrimaryListBox");
|
||||
primaryListBox?.SetValue(ItemsControl.ItemsSourceProperty, primaryCollection);
|
||||
|
||||
secondaryListBox = args.NameScope.Get<ListBox>("SecondaryListBox");
|
||||
secondaryListBox = args.NameScope.Get<OverflowList>("SecondaryListBox");
|
||||
secondaryListBox?.SetValue(ItemsControl.ItemsSourceProperty, secondaryCollection);
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user