Fixed various issues
This commit is contained in:
@@ -1,14 +1,17 @@
|
||||
using Avalonia.Controls;
|
||||
using Avalonia.Controls.Templates;
|
||||
using Avalonia.Data;
|
||||
using Avalonia.Interactivity;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Toolkit.Foundation;
|
||||
using Toolkit.UI.Controls.Avalonia;
|
||||
|
||||
namespace Toolkit.Avalonia;
|
||||
|
||||
public class ContentTemplate :
|
||||
IContentTemplate,
|
||||
IDataTemplate
|
||||
IDataTemplate,
|
||||
IItemContainerTemplateSelector
|
||||
{
|
||||
public Control? Build(object? item)
|
||||
{
|
||||
@@ -71,4 +74,64 @@ public class ContentTemplate :
|
||||
}
|
||||
|
||||
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;
|
||||
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
|
||||
x:Name="PrimaryListBox"
|
||||
Grid.Column="0"
|
||||
ItemContainerTemplateSelector="{TemplateBinding ItemContainerTemplateSelector}"
|
||||
ItemTemplate="{TemplateBinding ItemTemplate}"
|
||||
SelectedItem="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=TemplateSettings.PrimarySelection, Mode=TwoWay}">
|
||||
<controls:OverflowList.ItemsPanel>
|
||||
@@ -197,6 +198,7 @@
|
||||
<Flyout>
|
||||
<controls:OverflowList
|
||||
x:Name="SecondaryListBox"
|
||||
ItemContainerTemplateSelector="{TemplateBinding ItemContainerTemplateSelector}"
|
||||
ItemTemplate="{TemplateBinding ItemTemplate}"
|
||||
SelectedItem="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=TemplateSettings.SecondarySelection, Mode=TwoWay}">
|
||||
<controls:OverflowList.ItemsPanel>
|
||||
|
||||
@@ -14,6 +14,9 @@ namespace Toolkit.UI.Controls.Avalonia;
|
||||
public class Overflow :
|
||||
TemplatedControl
|
||||
{
|
||||
public static readonly StyledProperty<IItemContainerTemplateSelector?> ItemContainerTemplateSelectorProperty =
|
||||
AvaloniaProperty.Register<Overflow, IItemContainerTemplateSelector?>(nameof(ItemContainerTemplateSelector));
|
||||
|
||||
public static readonly StyledProperty<ITemplate<Panel?>> ItemsPanelProperty =
|
||||
AvaloniaProperty.Register<Overflow, ITemplate<Panel?>>(nameof(ItemsPanel), new FuncTemplate<Panel?>(() => new StackPanel()));
|
||||
|
||||
@@ -48,6 +51,12 @@ public class Overflow :
|
||||
.AddClassHandler<OverflowTemplateSettings>(OnSecondarySelectionPropertyChanged);
|
||||
}
|
||||
|
||||
public IItemContainerTemplateSelector? ItemContainerTemplateSelector
|
||||
{
|
||||
get => GetValue(ItemContainerTemplateSelectorProperty);
|
||||
set => SetValue(ItemContainerTemplateSelectorProperty, value);
|
||||
}
|
||||
|
||||
public ITemplate<Panel?> ItemsPanel
|
||||
{
|
||||
get => GetValue(ItemsPanelProperty);
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
using Avalonia.Controls;
|
||||
using Avalonia;
|
||||
using Avalonia.Controls;
|
||||
using Avalonia.Controls.Templates;
|
||||
|
||||
namespace Toolkit.UI.Controls.Avalonia;
|
||||
@@ -6,9 +7,18 @@ namespace Toolkit.UI.Controls.Avalonia;
|
||||
public class OverflowList :
|
||||
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)
|
||||
{
|
||||
if (recycleKey is IDataTemplate itemContainerTemplate)
|
||||
if (ItemContainerTemplateSelector?.SelectTemplate(item, this) is IDataTemplate itemContainerTemplate)
|
||||
{
|
||||
if (itemContainerTemplate.Build(item) is OverflowItem container)
|
||||
{
|
||||
@@ -19,21 +29,11 @@ public class OverflowList :
|
||||
return new OverflowItem();
|
||||
}
|
||||
|
||||
protected override bool NeedsContainerOverride(object? item, int index, out object? recycleKey)
|
||||
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;
|
||||
recycleKey = null;
|
||||
return item is not OverflowItem;
|
||||
}
|
||||
}
|
||||
@@ -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