feat: add closing feature.

This commit is contained in:
rabbitism
2023-06-29 02:25:31 +08:00
parent 9d249b01cd
commit 2d353ad9e0
5 changed files with 129 additions and 20 deletions

View File

@@ -9,10 +9,7 @@
<Setter Property="VerticalAlignment" Value="Top" />
<Setter Property="ItemTemplate">
<DataTemplate>
<Label
Classes="Solid"
Content="{Binding}"
Theme="{DynamicResource TagLabel}" />
<u:ClosableTag Command="{Binding $parent[u:TagInput].Close}" Content="{Binding}" />
</DataTemplate>
</Setter>
<Setter Property="Template">
@@ -24,6 +21,7 @@
CornerRadius="3">
<Panel HorizontalAlignment="Stretch">
<ItemsControl
Name="PART_ItemsControl"
HorizontalAlignment="Stretch"
VerticalAlignment="Top"
ItemTemplate="{TemplateBinding ItemTemplate}"
@@ -84,4 +82,34 @@
</ControlTemplate>
</Setter>
</ControlTheme>
<ControlTheme x:Key="{x:Type u:ClosableTag}" TargetType="u:ClosableTag">
<Setter Property="VerticalAlignment" Value="Center" />
<Setter Property="VerticalContentAlignment" Value="Center" />
<Setter Property="Template">
<ControlTemplate TargetType="u:ClosableTag">
<Border
Margin="1"
Background="Transparent"
BorderBrush="Black"
BorderThickness="1"
CornerRadius="3">
<DockPanel LastChildFill="True">
<PathIcon
Name="{x:Static u:ClosableTag.PART_CloseButton}"
Width="8"
Height="8"
Background="Transparent"
Data="M17.6568 19.7782C18.2426 20.3639 19.1924 20.3639 19.7782 19.7782C20.3639 19.1924 20.3639 18.2426 19.7782 17.6568L14.1213 12L19.7782 6.34313C20.3639 5.75734 20.3639 4.8076 19.7782 4.22181C19.1924 3.63602 18.2426 3.63602 17.6568 4.22181L12 9.87866L6.34313 4.22181C5.75734 3.63602 4.8076 3.63602 4.22181 4.22181C3.63602 4.8076 3.63602 5.75734 4.22181 6.34313L9.87866 12L4.22181 17.6568C3.63602 18.2426 3.63602 19.1924 4.22181 19.7782C4.8076 20.3639 5.75734 20.3639 6.34313 19.7782L12 14.1213L17.6568 19.7782Z"
DockPanel.Dock="Right" />
<TextBlock
VerticalAlignment="{TemplateBinding VerticalContentAlignment}"
FontSize="12"
Text="{TemplateBinding Content}"
TextTrimming="CharacterEllipsis" />
</DockPanel>
</Border>
</ControlTemplate>
</Setter>
</ControlTheme>
</ResourceDictionary>

View File

@@ -0,0 +1,46 @@
using System.Windows.Input;
using Avalonia;
using Avalonia.Controls;
using Avalonia.Controls.Metadata;
using Avalonia.Controls.Primitives;
using Avalonia.Input;
namespace Ursa.Controls;
[TemplatePart(PART_CloseButton, typeof(PathIcon))]
public class ClosableTag: ContentControl
{
public const string PART_CloseButton = "PART_CloseButton";
private PathIcon? _icon;
public static readonly StyledProperty<ICommand?> CommandProperty = AvaloniaProperty.Register<ClosableTag, ICommand?>(
nameof(Command));
public ICommand? Command
{
get => GetValue(CommandProperty);
set => SetValue(CommandProperty, value);
}
protected override void OnApplyTemplate(TemplateAppliedEventArgs e)
{
base.OnApplyTemplate(e);
if (_icon != null)
{
_icon.PointerPressed -= OnPointerPressed;
}
_icon = e.NameScope.Find<PathIcon>(PART_CloseButton);
if (_icon != null)
{
_icon.PointerPressed += OnPointerPressed;
}
}
private void OnPointerPressed(object? sender, PointerPressedEventArgs args)
{
if (Command != null && Command.CanExecute(null))
{
Command.Execute(this);
}
}
}

View File

@@ -1,21 +1,29 @@
using System.Collections;
using System.Collections.ObjectModel;
using Avalonia;
using Avalonia.Collections;
using Avalonia.Controls;
using Avalonia.Controls.Metadata;
using Avalonia.Controls.Presenters;
using Avalonia.Controls.Primitives;
using Avalonia.Controls.Templates;
using Avalonia.Input;
using Avalonia.Layout;
using Avalonia.Styling;
namespace Ursa.Controls;
[TemplatePart (PART_ItemsControl, typeof (ItemsControl))]
public class TagInput: TemplatedControl
{
public const string PART_ItemsControl = "PART_ItemsControl";
private readonly TextBox _textBox;
private ItemsControl? _itemsControl;
public static readonly StyledProperty<IList<string>> TagsProperty = AvaloniaProperty.Register<TagInput, IList<string>>(
nameof(Tags));
private TextBox _textBox;
public IList<string> Tags
{
get => GetValue(TagsProperty);
@@ -24,7 +32,6 @@ public class TagInput: TemplatedControl
public static readonly StyledProperty<IList> ItemsProperty = AvaloniaProperty.Register<TagInput, IList>(
nameof(Items));
public IList Items
{
get => GetValue(ItemsProperty);
@@ -34,6 +41,9 @@ public class TagInput: TemplatedControl
public TagInput()
{
_textBox = new TextBox();
_textBox.KeyDown += OnTextBoxKeyDown;
Items = new AvaloniaList<object>();
Tags = new ObservableCollection<string>();
}
public static readonly StyledProperty<ControlTheme> InputThemeProperty = AvaloniaProperty.Register<TagInput, ControlTheme>(
@@ -57,20 +67,42 @@ public class TagInput: TemplatedControl
protected override void OnApplyTemplate(TemplateAppliedEventArgs e)
{
base.OnApplyTemplate(e);
Items = new AvaloniaList<object>();
_itemsControl = e.NameScope.Find<ItemsControl>(PART_ItemsControl);
if (IsSet(InputThemeProperty) && InputTheme.TargetType == typeof(TextBox))
{
_textBox.Theme = InputTheme;
}
_textBox.KeyDown += (sender, args) =>
{
if (args.Key == Avalonia.Input.Key.Enter)
{
Items.Insert(Items.Count - 1, _textBox.Text);
// Tags.Insert(Items.Count - 1, _textBox.Text ?? string.Empty);
_textBox.Text = "";
}
};
Items.Add(_textBox);
}
private void OnTextBoxKeyDown(object? sender, KeyEventArgs args)
{
if (args.Key == Avalonia.Input.Key.Enter)
{
if (_textBox.Text?.Length > 0)
{
Items.Insert(Items.Count - 1, _textBox.Text);
Tags.Insert(Items.Count - 2, _textBox.Text ?? string.Empty);
_textBox.Text = "";
}
}
}
public void Close(object o)
{
if (o is ClosableTag t)
{
var presenter = t.Parent as ContentPresenter;
if (presenter != null)
{
int? index = _itemsControl?.IndexFromContainer(presenter);
if (index is >= 0 && index < Items.Count - 1)
{
Items.RemoveAt(index.Value);
Tags.RemoveAt(index.Value);
}
}
}
}
}

View File

@@ -82,7 +82,7 @@ public class TagInputPanel: Panel
else
{
totalHeight += currentLineHeight;
child.Arrange(new Rect(0, totalHeight, finalSize.Width, child.DesiredSize.Height));
child.Arrange(new Rect(0, totalHeight, Math.Min(child.DesiredSize.Width, finalSize.Width), child.DesiredSize.Height));
currentLineX = child.DesiredSize.Width;
currentLineHeight = child.DesiredSize.Height;
}