Fixed various issues
This commit is contained in:
@@ -1,14 +1,17 @@
|
|||||||
using Avalonia.Controls;
|
using Avalonia.Controls;
|
||||||
using Avalonia.Controls.Templates;
|
using Avalonia.Controls.Templates;
|
||||||
|
using Avalonia.Data;
|
||||||
using Avalonia.Interactivity;
|
using Avalonia.Interactivity;
|
||||||
using Microsoft.Extensions.DependencyInjection;
|
using Microsoft.Extensions.DependencyInjection;
|
||||||
using Toolkit.Foundation;
|
using Toolkit.Foundation;
|
||||||
|
using Toolkit.UI.Controls.Avalonia;
|
||||||
|
|
||||||
namespace Toolkit.Avalonia;
|
namespace Toolkit.Avalonia;
|
||||||
|
|
||||||
public class ContentTemplate :
|
public class ContentTemplate :
|
||||||
IContentTemplate,
|
IContentTemplate,
|
||||||
IDataTemplate
|
IDataTemplate,
|
||||||
|
IItemContainerTemplateSelector
|
||||||
{
|
{
|
||||||
public Control? Build(object? item)
|
public Control? Build(object? item)
|
||||||
{
|
{
|
||||||
@@ -71,4 +74,64 @@ public class ContentTemplate :
|
|||||||
}
|
}
|
||||||
|
|
||||||
public bool Match(object? data) => true;
|
public bool Match(object? data) => true;
|
||||||
|
|
||||||
|
public IDataTemplate? SelectTemplate(object? item, ItemsControl itemsControl)
|
||||||
|
{
|
||||||
|
if (item is IObservableViewModel observableViewModel)
|
||||||
|
{
|
||||||
|
if (observableViewModel.Provider is IServiceProvider provider)
|
||||||
|
{
|
||||||
|
Type itemType = item.GetType();
|
||||||
|
if (provider.GetRequiredKeyedService<IContentTemplateDescriptor>(itemType.Name.Replace("ViewModel", ""))
|
||||||
|
is IContentTemplateDescriptor descriptor)
|
||||||
|
{
|
||||||
|
if (provider.GetRequiredKeyedService(descriptor.TemplateType, descriptor.Key) is Control control)
|
||||||
|
{
|
||||||
|
async void HandleLoaded(object? sender, RoutedEventArgs args)
|
||||||
|
{
|
||||||
|
control.Loaded -= HandleLoaded;
|
||||||
|
if (control.DataContext is object content)
|
||||||
|
{
|
||||||
|
if (content is IActivated activated)
|
||||||
|
{
|
||||||
|
await activated.OnActivated();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async void HandleDataContextChanged(object? sender, EventArgs args)
|
||||||
|
{
|
||||||
|
if (control.DataContext is object content)
|
||||||
|
{
|
||||||
|
if (content is IActivated activated)
|
||||||
|
{
|
||||||
|
await activated.OnActivated();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async void HandleUnloaded(object? sender, RoutedEventArgs args)
|
||||||
|
{
|
||||||
|
control.Unloaded -= HandleUnloaded;
|
||||||
|
if (control.DataContext is object content)
|
||||||
|
{
|
||||||
|
if (content is IDeactivated deactivated)
|
||||||
|
{
|
||||||
|
await deactivated.OnDeactivated();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
control.Loaded += HandleLoaded;
|
||||||
|
control.Unloaded += HandleUnloaded;
|
||||||
|
control.DataContextChanged += HandleDataContextChanged; ;
|
||||||
|
|
||||||
|
return new FuncDataTemplate(item.GetType(), (_, _) => control);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return default;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@@ -39,11 +39,6 @@ public class ListBoxExtension
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (sender.DataContext == listBox.SelectedItem)
|
|
||||||
{
|
|
||||||
sender.RaiseEvent(new ItemInvokedEventArgs { RoutedEvent = ItemInvokedEvent });
|
|
||||||
}
|
|
||||||
|
|
||||||
listBox.SelectionChanged += OnItemInvoked;
|
listBox.SelectionChanged += OnItemInvoked;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,41 @@
|
|||||||
|
using Avalonia;
|
||||||
|
using Avalonia.Controls;
|
||||||
|
using Avalonia.Controls.Templates;
|
||||||
|
|
||||||
|
namespace Toolkit.UI.Controls.Avalonia;
|
||||||
|
public class ListView :
|
||||||
|
ListBox
|
||||||
|
{
|
||||||
|
public static readonly StyledProperty<IItemContainerTemplateSelector?> ItemContainerTemplateSelectorProperty =
|
||||||
|
AvaloniaProperty.Register<ListView, IItemContainerTemplateSelector?>(nameof(ItemContainerTemplateSelector));
|
||||||
|
|
||||||
|
public IItemContainerTemplateSelector? ItemContainerTemplateSelector
|
||||||
|
{
|
||||||
|
get => GetValue(ItemContainerTemplateSelectorProperty);
|
||||||
|
set => SetValue(ItemContainerTemplateSelectorProperty, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override Type StyleKeyOverride =>
|
||||||
|
typeof(ListBox);
|
||||||
|
|
||||||
|
protected override Control CreateContainerForItemOverride(object? item, int index, object? recycleKey)
|
||||||
|
{
|
||||||
|
if (ItemContainerTemplateSelector?.SelectTemplate(item, this) is IDataTemplate itemContainerTemplate)
|
||||||
|
{
|
||||||
|
if (itemContainerTemplate.Build(item) is ListViewItem container)
|
||||||
|
{
|
||||||
|
return container;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return new ListViewItem();
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override bool NeedsContainerOverride(object? item,
|
||||||
|
int index,
|
||||||
|
out object? recycleKey)
|
||||||
|
{
|
||||||
|
recycleKey = null;
|
||||||
|
return item is not ListViewItem;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,10 @@
|
|||||||
|
using Avalonia.Controls;
|
||||||
|
|
||||||
|
namespace Toolkit.UI.Controls.Avalonia;
|
||||||
|
|
||||||
|
public class ListViewItem :
|
||||||
|
ListBoxItem
|
||||||
|
{
|
||||||
|
protected override Type StyleKeyOverride =>
|
||||||
|
typeof(ListBoxItem);
|
||||||
|
}
|
||||||
@@ -162,6 +162,7 @@
|
|||||||
<controls:OverflowList
|
<controls:OverflowList
|
||||||
x:Name="PrimaryListBox"
|
x:Name="PrimaryListBox"
|
||||||
Grid.Column="0"
|
Grid.Column="0"
|
||||||
|
ItemContainerTemplateSelector="{TemplateBinding ItemContainerTemplateSelector}"
|
||||||
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}">
|
||||||
<controls:OverflowList.ItemsPanel>
|
<controls:OverflowList.ItemsPanel>
|
||||||
@@ -197,6 +198,7 @@
|
|||||||
<Flyout>
|
<Flyout>
|
||||||
<controls:OverflowList
|
<controls:OverflowList
|
||||||
x:Name="SecondaryListBox"
|
x:Name="SecondaryListBox"
|
||||||
|
ItemContainerTemplateSelector="{TemplateBinding ItemContainerTemplateSelector}"
|
||||||
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}">
|
||||||
<controls:OverflowList.ItemsPanel>
|
<controls:OverflowList.ItemsPanel>
|
||||||
|
|||||||
@@ -14,6 +14,9 @@ namespace Toolkit.UI.Controls.Avalonia;
|
|||||||
public class Overflow :
|
public class Overflow :
|
||||||
TemplatedControl
|
TemplatedControl
|
||||||
{
|
{
|
||||||
|
public static readonly StyledProperty<IItemContainerTemplateSelector?> ItemContainerTemplateSelectorProperty =
|
||||||
|
AvaloniaProperty.Register<Overflow, IItemContainerTemplateSelector?>(nameof(ItemContainerTemplateSelector));
|
||||||
|
|
||||||
public static readonly StyledProperty<ITemplate<Panel?>> ItemsPanelProperty =
|
public static readonly StyledProperty<ITemplate<Panel?>> ItemsPanelProperty =
|
||||||
AvaloniaProperty.Register<Overflow, ITemplate<Panel?>>(nameof(ItemsPanel), new FuncTemplate<Panel?>(() => new StackPanel()));
|
AvaloniaProperty.Register<Overflow, ITemplate<Panel?>>(nameof(ItemsPanel), new FuncTemplate<Panel?>(() => new StackPanel()));
|
||||||
|
|
||||||
@@ -48,6 +51,12 @@ public class Overflow :
|
|||||||
.AddClassHandler<OverflowTemplateSettings>(OnSecondarySelectionPropertyChanged);
|
.AddClassHandler<OverflowTemplateSettings>(OnSecondarySelectionPropertyChanged);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public IItemContainerTemplateSelector? ItemContainerTemplateSelector
|
||||||
|
{
|
||||||
|
get => GetValue(ItemContainerTemplateSelectorProperty);
|
||||||
|
set => SetValue(ItemContainerTemplateSelectorProperty, value);
|
||||||
|
}
|
||||||
|
|
||||||
public ITemplate<Panel?> ItemsPanel
|
public ITemplate<Panel?> ItemsPanel
|
||||||
{
|
{
|
||||||
get => GetValue(ItemsPanelProperty);
|
get => GetValue(ItemsPanelProperty);
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
using Avalonia.Controls;
|
using Avalonia;
|
||||||
|
using Avalonia.Controls;
|
||||||
using Avalonia.Controls.Templates;
|
using Avalonia.Controls.Templates;
|
||||||
|
|
||||||
namespace Toolkit.UI.Controls.Avalonia;
|
namespace Toolkit.UI.Controls.Avalonia;
|
||||||
@@ -6,9 +7,18 @@ namespace Toolkit.UI.Controls.Avalonia;
|
|||||||
public class OverflowList :
|
public class OverflowList :
|
||||||
ListBox
|
ListBox
|
||||||
{
|
{
|
||||||
|
public static readonly StyledProperty<IItemContainerTemplateSelector?> ItemContainerTemplateSelectorProperty =
|
||||||
|
AvaloniaProperty.Register<OverflowList, IItemContainerTemplateSelector?>(nameof(ItemContainerTemplateSelector));
|
||||||
|
|
||||||
|
public IItemContainerTemplateSelector? ItemContainerTemplateSelector
|
||||||
|
{
|
||||||
|
get => GetValue(ItemContainerTemplateSelectorProperty);
|
||||||
|
set => SetValue(ItemContainerTemplateSelectorProperty, value);
|
||||||
|
}
|
||||||
|
|
||||||
protected override Control CreateContainerForItemOverride(object? item, int index, object? recycleKey)
|
protected override Control CreateContainerForItemOverride(object? item, int index, object? recycleKey)
|
||||||
{
|
{
|
||||||
if (recycleKey is IDataTemplate itemContainerTemplate)
|
if (ItemContainerTemplateSelector?.SelectTemplate(item, this) is IDataTemplate itemContainerTemplate)
|
||||||
{
|
{
|
||||||
if (itemContainerTemplate.Build(item) is OverflowItem container)
|
if (itemContainerTemplate.Build(item) is OverflowItem container)
|
||||||
{
|
{
|
||||||
@@ -19,21 +29,11 @@ public class OverflowList :
|
|||||||
return new OverflowItem();
|
return new OverflowItem();
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override bool NeedsContainerOverride(object? item, int index, out object? recycleKey)
|
protected override bool NeedsContainerOverride(object? item,
|
||||||
{
|
int index,
|
||||||
if (item is OverflowItem)
|
out object? recycleKey)
|
||||||
{
|
{
|
||||||
recycleKey = null;
|
recycleKey = null;
|
||||||
return false;
|
return item is not OverflowItem;
|
||||||
}
|
|
||||||
|
|
||||||
if (this.FindDataTemplate(item, ItemTemplate) is IDataTemplate itemContainerTemplate)
|
|
||||||
{
|
|
||||||
recycleKey = itemContainerTemplate;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
recycleKey = DefaultRecycleKey;
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1,42 +0,0 @@
|
|||||||
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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -0,0 +1,9 @@
|
|||||||
|
using Avalonia.Controls;
|
||||||
|
using Avalonia.Controls.Templates;
|
||||||
|
|
||||||
|
namespace Toolkit.UI.Controls.Avalonia;
|
||||||
|
|
||||||
|
public interface IItemContainerTemplateSelector
|
||||||
|
{
|
||||||
|
IDataTemplate? SelectTemplate(object? item, ItemsControl itemsControl);
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user