feat: implement inner content interface.

This commit is contained in:
rabbitism
2025-09-16 19:20:02 +08:00
parent 7603206b3d
commit 0173ee7c9c
5 changed files with 76 additions and 30 deletions

View File

@@ -7,9 +7,11 @@
mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="450"
x:DataType="vm:MultiAutoCompleteBoxDemoViewModel"
x:Class="Ursa.Demo.Pages.MultiAutoCompleteBoxDemo">
<StackPanel Spacing="20">
<StackPanel Spacing="20" HorizontalAlignment="Left">
<TextBlock Text="Multi-AutoCompleteBox"/>
<u:MultiAutoCompleteBox ItemsSource="{Binding Items}"
MaxWidth="400"
InnerLeftContent="Controls"
SelectedItems="{Binding SelectedItems}"
ItemFilter="{Binding FilterPredicate }"
FilterMode="Custom">

View File

@@ -1,4 +1,5 @@
using System.Collections.Generic;
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using Avalonia.Controls;
using CommunityToolkit.Mvvm.ComponentModel;
@@ -82,12 +83,13 @@ public class MultiAutoCompleteBoxDemoViewModel: ObservableObject
{
if (text is null) return true;
if (data is not ControlData control) return false;
return control.MenuHeader.Contains(text )|| control.Chinese.Contains(text);
return control.MenuHeader.Contains(text, StringComparison.InvariantCultureIgnoreCase) ||
control.Chinese.Contains(text, StringComparison.InvariantCultureIgnoreCase);
}
}
public class ControlData
{
public string MenuHeader { get; set; }
public string Chinese { get; set; }
public required string MenuHeader { get; init; }
public required string Chinese { get; init; }
}

View File

@@ -12,12 +12,22 @@
<Border
Name="PART_RootBorder"
MinHeight="30"
Padding="{DynamicResource TextBoxContentPadding}"
VerticalAlignment="Stretch"
CornerRadius="{TemplateBinding CornerRadius}"
Background="{DynamicResource TextBoxDefaultBackground}"
BorderBrush="{DynamicResource TextBoxDefaultBorderBrush}">
<Grid ColumnDefinitions="Auto, *, Auto">
<ContentPresenter
Grid.Column="0"
Margin="8,0"
IsHitTestVisible="False"
VerticalAlignment="Center"
Content="{TemplateBinding InnerLeftContent}"
Foreground="{DynamicResource TextBoxInnerForeground}"
IsVisible="{TemplateBinding InnerLeftContent,
Converter={x:Static ObjectConverters.IsNotNull}}" />
<u:MultiComboBoxSelectedItemList
Grid.Column="1"
Name="{x:Static u:MultiAutoCompleteBox.PART_SelectedItemsControl}"
VerticalAlignment="Center"
RemoveCommand="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=Remove}"
@@ -33,6 +43,16 @@
</ItemsPanelTemplate>
</u:MultiComboBoxSelectedItemList.ItemsPanel>
</u:MultiComboBoxSelectedItemList>
<ContentPresenter
Grid.Column="2"
Margin="8,0"
VerticalAlignment="Center"
IsHitTestVisible="False"
Content="{TemplateBinding InnerRightContent}"
Foreground="{DynamicResource TextBoxInnerForeground}"
IsVisible="{TemplateBinding InnerRightContent,
Converter={x:Static ObjectConverters.IsNotNull}}" />
</Grid>
</Border>
<Popup
Name="PART_Popup"
@@ -49,12 +69,16 @@
BorderThickness="{DynamicResource AutoCompleteBoxPopupBorderThickness}"
BoxShadow="{DynamicResource AutoCompleteBoxPopupBoxShadow}"
CornerRadius="{DynamicResource AutoCompleteBoxPopupCornerRadius}">
<DockPanel LastChildFill="True">
<ContentPresenter Content="{TemplateBinding PopupInnerTopContent}" DockPanel.Dock="Top" />
<ContentPresenter Content="{TemplateBinding PopupInnerBottomContent}" DockPanel.Dock="Bottom" />
<ListBox
Name="PART_SelectingItemsControl"
Foreground="{TemplateBinding Foreground}"
ItemTemplate="{TemplateBinding ItemTemplate}"
ScrollViewer.HorizontalScrollBarVisibility="Auto"
ScrollViewer.VerticalScrollBarVisibility="Auto" />
</DockPanel>
</Border>
</Popup>
</Panel>

View File

@@ -512,4 +512,22 @@ public partial class MultiAutoCompleteBox
get => GetValue(InnerRightContentProperty);
set => SetValue(InnerRightContentProperty, value);
}
public static readonly StyledProperty<object?> PopupInnerTopContentProperty = AvaloniaProperty.Register<MultiAutoCompleteBox, object?>(
nameof(PopupInnerTopContent));
public object? PopupInnerTopContent
{
get => GetValue(PopupInnerTopContentProperty);
set => SetValue(PopupInnerTopContentProperty, value);
}
public static readonly StyledProperty<object?> PopupInnerBottomContentProperty = AvaloniaProperty.Register<MultiAutoCompleteBox, object?>(
nameof(PopupInnerBottomContent));
public object? PopupInnerBottomContent
{
get => GetValue(PopupInnerBottomContentProperty);
set => SetValue(PopupInnerBottomContentProperty, value);
}
}

View File

@@ -30,7 +30,7 @@ namespace Ursa.Controls;
[TemplatePart(ElementSelectionAdapter, typeof(ISelectionAdapter))]
[TemplatePart(ElementTextBox, typeof(TextBox))]
[PseudoClasses(":dropdownopen")]
public partial class MultiAutoCompleteBox : TemplatedControl, IInnerContentControl
public partial class MultiAutoCompleteBox : TemplatedControl, IInnerContentControl, IPopupInnerContent
{
/// <summary>
/// Specifies the name of the selection adapter TemplatePart.