diff --git a/demo/Ursa.Demo/Converters/MenuDataTemplateSelector.cs b/demo/Ursa.Demo/Converters/MenuDataTemplateSelector.cs index a91b109..03d73d1 100644 --- a/demo/Ursa.Demo/Converters/MenuDataTemplateSelector.cs +++ b/demo/Ursa.Demo/Converters/MenuDataTemplateSelector.cs @@ -11,12 +11,11 @@ public class MenuDataTemplateSelector: IDataTemplate public Control? Build(object? param) { - if (param is NavigationMenuItemViewModel vm) + if (param is MenuItemViewModel vm) { if (vm.IsSeparator) return SeparatorTemplate?.Build(vm); else return MenuTemplate?.Build(vm); } - return null; } diff --git a/demo/Ursa.Demo/Converters/ViewLocator.cs b/demo/Ursa.Demo/Converters/ViewLocator.cs new file mode 100644 index 0000000..fbbbece --- /dev/null +++ b/demo/Ursa.Demo/Converters/ViewLocator.cs @@ -0,0 +1,29 @@ +using System; +using Avalonia.Controls; +using Avalonia.Controls.Templates; +using Ursa.Demo.Pages; + +namespace Ursa.Demo.Converters; + +public class ViewLocator: IDataTemplate +{ + public Control? Build(object? param) + { + if (param is null) return null; + var name = param.GetType().Name!.Replace("ViewModel", ""); + var type = Type.GetType("Ursa.Demo.Pages."+name); + if (type != null) + { + return (Control)Activator.CreateInstance(type)!; + } + else + { + return new TextBlock { Text = "Not Found: " + name }; + } + } + + public bool Match(object? data) + { + return true; + } +} \ No newline at end of file diff --git a/demo/Ursa.Demo/Models/MenuKeys.cs b/demo/Ursa.Demo/Models/MenuKeys.cs new file mode 100644 index 0000000..5a76eb9 --- /dev/null +++ b/demo/Ursa.Demo/Models/MenuKeys.cs @@ -0,0 +1,15 @@ +namespace Ursa.Demo; + +public static class MenuKeys +{ + public const string MenuKeyBadge = "Badge"; + public const string MenuKeyBanner = "Banner"; + public const string MenuKeyButtonGroup = "ButtonGroup"; + public const string MenuKeyDivider = "Divider"; + public const string MenuKeyIpBox = "IPv4Box"; + public const string MenuKeyLoading = "Loading"; + public const string MenuKeyNavigation = "Navigation"; + public const string MenuKeyPagination = "Pagination"; + public const string MenuKeyTagInput = "TagInput"; + public const string MenuKeyTimeline = "Timeline"; +} \ No newline at end of file diff --git a/demo/Ursa.Demo/Pages/ButtonGroupDemo.axaml b/demo/Ursa.Demo/Pages/ButtonGroupDemo.axaml index 510c423..30c0a03 100644 --- a/demo/Ursa.Demo/Pages/ButtonGroupDemo.axaml +++ b/demo/Ursa.Demo/Pages/ButtonGroupDemo.axaml @@ -9,7 +9,7 @@ d:DesignHeight="450" d:DesignWidth="800" x:CompileBindings="True" - x:DataType="vm:ButtonGroupViewModel" + x:DataType="vm:ButtonGroupDemoViewModel" mc:Ignorable="d"> diff --git a/demo/Ursa.Demo/Pages/ButtonGroupDemo.axaml.cs b/demo/Ursa.Demo/Pages/ButtonGroupDemo.axaml.cs index 695bcd1..533130a 100644 --- a/demo/Ursa.Demo/Pages/ButtonGroupDemo.axaml.cs +++ b/demo/Ursa.Demo/Pages/ButtonGroupDemo.axaml.cs @@ -10,6 +10,6 @@ public partial class ButtonGroupDemo : UserControl public ButtonGroupDemo() { InitializeComponent(); - this.DataContext = new ButtonGroupViewModel(); + this.DataContext = new ButtonGroupDemoViewModel(); } } \ No newline at end of file diff --git a/demo/Ursa.Demo/Pages/NavigationMenuDemo.axaml b/demo/Ursa.Demo/Pages/NavigationMenuDemo.axaml index 8e608a7..651c3e8 100644 --- a/demo/Ursa.Demo/Pages/NavigationMenuDemo.axaml +++ b/demo/Ursa.Demo/Pages/NavigationMenuDemo.axaml @@ -42,7 +42,7 @@ - + - + diff --git a/demo/Ursa.Demo/Ursa.Demo.csproj b/demo/Ursa.Demo/Ursa.Demo.csproj index 328116c..f11d2df 100644 --- a/demo/Ursa.Demo/Ursa.Demo.csproj +++ b/demo/Ursa.Demo/Ursa.Demo.csproj @@ -9,7 +9,6 @@ - diff --git a/demo/Ursa.Demo/ViewModels/BadgeDemoViewModel.cs b/demo/Ursa.Demo/ViewModels/BadgeDemoViewModel.cs new file mode 100644 index 0000000..afd9963 --- /dev/null +++ b/demo/Ursa.Demo/ViewModels/BadgeDemoViewModel.cs @@ -0,0 +1,6 @@ +namespace Ursa.Demo.ViewModels; + +public class BadgeDemoViewModel: ViewModelBase +{ + +} \ No newline at end of file diff --git a/demo/Ursa.Demo/ViewModels/BannerDemoViewModel.cs b/demo/Ursa.Demo/ViewModels/BannerDemoViewModel.cs new file mode 100644 index 0000000..34a0ded --- /dev/null +++ b/demo/Ursa.Demo/ViewModels/BannerDemoViewModel.cs @@ -0,0 +1,6 @@ +namespace Ursa.Demo.ViewModels; + +public class BannerDemoViewModel: ViewModelBase +{ + +} \ No newline at end of file diff --git a/demo/Ursa.Demo/ViewModels/ButtonGroupViewModel.cs b/demo/Ursa.Demo/ViewModels/ButtonGroupDemoViewModel.cs similarity index 71% rename from demo/Ursa.Demo/ViewModels/ButtonGroupViewModel.cs rename to demo/Ursa.Demo/ViewModels/ButtonGroupDemoViewModel.cs index aeb2400..88c5299 100644 --- a/demo/Ursa.Demo/ViewModels/ButtonGroupViewModel.cs +++ b/demo/Ursa.Demo/ViewModels/ButtonGroupDemoViewModel.cs @@ -2,9 +2,9 @@ using System.Collections.ObjectModel; namespace Ursa.Demo.ViewModels; -public class ButtonGroupViewModel: ViewModelBase +public class ButtonGroupDemoViewModel: ViewModelBase { - public ObservableCollection Items { get; set; } = new ObservableCollection() + public ObservableCollection Items { get; set; } = new () { "Ding", "Otter", "Husky", "Mr. 17", "Cass" }; diff --git a/demo/Ursa.Demo/ViewModels/DividerDemoViewModel.cs b/demo/Ursa.Demo/ViewModels/DividerDemoViewModel.cs new file mode 100644 index 0000000..a7b433c --- /dev/null +++ b/demo/Ursa.Demo/ViewModels/DividerDemoViewModel.cs @@ -0,0 +1,6 @@ +namespace Ursa.Demo.ViewModels; + +public class DividerDemoViewModel: ViewModelBase +{ + +} \ No newline at end of file diff --git a/demo/Ursa.Demo/ViewModels/IPv4BoxDemoViewModel.cs b/demo/Ursa.Demo/ViewModels/IPv4BoxDemoViewModel.cs new file mode 100644 index 0000000..ff17a77 --- /dev/null +++ b/demo/Ursa.Demo/ViewModels/IPv4BoxDemoViewModel.cs @@ -0,0 +1,6 @@ +namespace Ursa.Demo.ViewModels; + +public class IPv4BoxDemoViewModel: ViewModelBase +{ + +} \ No newline at end of file diff --git a/demo/Ursa.Demo/ViewModels/LoadingDemoViewModel.cs b/demo/Ursa.Demo/ViewModels/LoadingDemoViewModel.cs new file mode 100644 index 0000000..0239ec1 --- /dev/null +++ b/demo/Ursa.Demo/ViewModels/LoadingDemoViewModel.cs @@ -0,0 +1,6 @@ +namespace Ursa.Demo.ViewModels; + +public class LoadingDemoViewModel: ViewModelBase +{ + +} \ No newline at end of file diff --git a/demo/Ursa.Demo/ViewModels/MainWindowViewModel.cs b/demo/Ursa.Demo/ViewModels/MainWindowViewModel.cs index 9ac0155..7fdbd75 100644 --- a/demo/Ursa.Demo/ViewModels/MainWindowViewModel.cs +++ b/demo/Ursa.Demo/ViewModels/MainWindowViewModel.cs @@ -1,6 +1,40 @@ -namespace Ursa.Demo.ViewModels; + +using CommunityToolkit.Mvvm.Messaging; + +namespace Ursa.Demo.ViewModels; public class MainWindowViewModel : ViewModelBase { - public string Greeting => "Welcome to Avalonia!"; + public MenuViewModel Menus { get; set; } = new MenuViewModel(); + + private object? _content; + public object? Content + { + get => _content; + set => SetProperty(ref _content, value); + } + + public MainWindowViewModel() + { + WeakReferenceMessenger.Default.Register(this, OnNavigation); + } + + + + private void OnNavigation(MainWindowViewModel vm, string s) + { + Content = s switch + { + MenuKeys.MenuKeyBadge => new BadgeDemoViewModel(), + MenuKeys.MenuKeyBanner => new BannerDemoViewModel(), + MenuKeys.MenuKeyButtonGroup => new ButtonGroupDemoViewModel(), + MenuKeys.MenuKeyDivider => new DividerDemoViewModel(), + MenuKeys.MenuKeyIpBox => new IPv4BoxDemoViewModel(), + MenuKeys.MenuKeyLoading => new LoadingDemoViewModel(), + MenuKeys.MenuKeyNavigation => new NavigationMenuDemoViewModel(), + MenuKeys.MenuKeyPagination => new PaginationDemoViewModel(), + MenuKeys.MenuKeyTagInput => new TagInputDemoViewModel(), + MenuKeys.MenuKeyTimeline => new TimelineDemoViewModel(), + }; + } } \ No newline at end of file diff --git a/demo/Ursa.Demo/ViewModels/MenuItemViewModel.cs b/demo/Ursa.Demo/ViewModels/MenuItemViewModel.cs new file mode 100644 index 0000000..42be205 --- /dev/null +++ b/demo/Ursa.Demo/ViewModels/MenuItemViewModel.cs @@ -0,0 +1,29 @@ +using System.Collections.ObjectModel; +using System.Windows.Input; +using CommunityToolkit.Mvvm.Input; +using CommunityToolkit.Mvvm.Messaging; + +namespace Ursa.Demo.ViewModels; + +public class MenuItemViewModel: ViewModelBase +{ + public string MenuHeader { get; set; } + public string MenuIconName { get; set; } + public string Key { get; set; } + + public bool IsSeparator { get; set; } + public ObservableCollection Children { get; set; } = new(); + + public ICommand ActivateCommand { get; set; } + + public MenuItemViewModel() + { + ActivateCommand = new RelayCommand(OnActivate); + } + + private void OnActivate() + { + if (IsSeparator) return; + WeakReferenceMessenger.Default.Send(Key); + } +} \ No newline at end of file diff --git a/demo/Ursa.Demo/ViewModels/MenuViewModel.cs b/demo/Ursa.Demo/ViewModels/MenuViewModel.cs new file mode 100644 index 0000000..9351ad9 --- /dev/null +++ b/demo/Ursa.Demo/ViewModels/MenuViewModel.cs @@ -0,0 +1,26 @@ +using System.Collections.ObjectModel; + +namespace Ursa.Demo.ViewModels; + +public class MenuViewModel: ViewModelBase +{ + public ObservableCollection MenuItems { get; set; } + + public MenuViewModel() + { + MenuItems = new ObservableCollection() + { + new() { MenuHeader = "Controls", IsSeparator = true }, + new() { MenuHeader = "Badge", Key = MenuKeys.MenuKeyBadge }, + new() { MenuHeader = "Banner", Key = MenuKeys.MenuKeyBanner }, + new() { MenuHeader = "ButtonGroup", Key = MenuKeys.MenuKeyButtonGroup }, + new() { MenuHeader = "Divider", Key = MenuKeys.MenuKeyDivider }, + new() { MenuHeader = "IPv4Box", Key = MenuKeys.MenuKeyIpBox }, + new() { MenuHeader = "Loading", Key = MenuKeys.MenuKeyLoading }, + new() { MenuHeader = "Navigation", Key = MenuKeys.MenuKeyNavigation }, + new() { MenuHeader = "Pagination", Key = MenuKeys.MenuKeyPagination }, + new() { MenuHeader = "TagInput", Key = MenuKeys.MenuKeyTagInput }, + new() { MenuHeader = "Timeline", Key = MenuKeys.MenuKeyTimeline }, + }; + } +} \ No newline at end of file diff --git a/demo/Ursa.Demo/ViewModels/NavigationMenuDemoViewModel.cs b/demo/Ursa.Demo/ViewModels/NavigationMenuDemoViewModel.cs index 4b7c0c6..7633771 100644 --- a/demo/Ursa.Demo/ViewModels/NavigationMenuDemoViewModel.cs +++ b/demo/Ursa.Demo/ViewModels/NavigationMenuDemoViewModel.cs @@ -5,18 +5,18 @@ namespace Ursa.Demo.ViewModels; public class NavigationMenuDemoViewModel: ObservableObject { - public ObservableCollection MenuItems { get; set; } = new() + public ObservableCollection MenuItems { get; set; } = new() { - new NavigationMenuItemViewModel() + new MenuItemViewModel() { MenuHeader = "任务管理", MenuIconName = "User", - Children = new ObservableCollection() + Children = new ObservableCollection() { new (){ MenuHeader = "公告管理" , MenuIconName = "Star", - Children = new ObservableCollection() + Children = new ObservableCollection() { new () {MenuHeader = "公告设置"}, new () {MenuHeader = "公告处理"} @@ -24,16 +24,16 @@ public class NavigationMenuDemoViewModel: ObservableObject new (){MenuHeader = "任务查询"} } }, - new NavigationMenuItemViewModel() + new MenuItemViewModel() { MenuHeader = "附加功能", IsSeparator = true, }, - new NavigationMenuItemViewModel() + new MenuItemViewModel() { MenuHeader = "任务平台", MenuIconName = "Gear", - Children = new ObservableCollection() + Children = new ObservableCollection() { new (){MenuHeader = "任务管理"}, new (){MenuHeader = "用户任务查询"} @@ -42,11 +42,3 @@ public class NavigationMenuDemoViewModel: ObservableObject }; } -public class NavigationMenuItemViewModel: ObservableObject -{ - public string MenuHeader { get; set; } - public string MenuIconName { get; set; } - - public bool IsSeparator { get; set; } - public ObservableCollection Children { get; set; } = new(); -} \ No newline at end of file diff --git a/demo/Ursa.Demo/ViewModels/PaginationDemoViewModel.cs b/demo/Ursa.Demo/ViewModels/PaginationDemoViewModel.cs index bf69393..55bb942 100644 --- a/demo/Ursa.Demo/ViewModels/PaginationDemoViewModel.cs +++ b/demo/Ursa.Demo/ViewModels/PaginationDemoViewModel.cs @@ -5,7 +5,7 @@ using CommunityToolkit.Mvvm.ComponentModel; namespace Ursa.Demo.ViewModels; -public class PaginationDemoViewModel: ObservableObject +public class PaginationDemoViewModel: ViewModelBase { public AvaloniaList PageSizes { get; set; } = new() { 10, 20, 50, 100 }; } \ No newline at end of file diff --git a/demo/Ursa.Demo/ViewModels/TagInputDemoViewModel.cs b/demo/Ursa.Demo/ViewModels/TagInputDemoViewModel.cs new file mode 100644 index 0000000..dfcdb38 --- /dev/null +++ b/demo/Ursa.Demo/ViewModels/TagInputDemoViewModel.cs @@ -0,0 +1,6 @@ +namespace Ursa.Demo.ViewModels; + +public class TagInputDemoViewModel: ViewModelBase +{ + +} \ No newline at end of file diff --git a/demo/Ursa.Demo/ViewModels/TimelineDemoViewModel.cs b/demo/Ursa.Demo/ViewModels/TimelineDemoViewModel.cs index 2420ee3..fc9e819 100644 --- a/demo/Ursa.Demo/ViewModels/TimelineDemoViewModel.cs +++ b/demo/Ursa.Demo/ViewModels/TimelineDemoViewModel.cs @@ -4,7 +4,7 @@ using Ursa.Controls; namespace Ursa.Demo.ViewModels; -public class TimelineDemoViewModel: ObservableObject +public class TimelineDemoViewModel: ViewModelBase { public TimelineItemViewModel[] Items { get; } = { @@ -46,62 +46,6 @@ public class TimelineDemoViewModel: ObservableObject Description = "Item 5", Content = "Content 5" }, - new() - { - Time = DateTime.Now, - TimeFormat = "HH:mm:ss", - Description = "Item 6", - Content = "Content 6" - }, - new() - { - Time = DateTime.Now, - TimeFormat = "HH:mm:ss", - Description = "Item 7", - Content = "Content 71231" - }, - new() - { - Time = DateTime.Now, - TimeFormat = "HH:mm:ss", - Description = "Item 8", - Content = "Content 8123123" - }, - new() - { - Time = DateTime.Now, - TimeFormat = "HH:mm:ss", - Description = "Item 9", - Content = "Content 9123123" - }, - new() - { - Time = DateTime.Now, - TimeFormat = "HH:mm:ss", - Description = "Item 10", - Content = "Content 1231231231231231231230" - }, - new() - { - Time = DateTime.Now, - TimeFormat = "HH:mm:ss", - Description = "Item 11", - Content = "Content 11231231" - }, - new() - { - Time = DateTime.Now, - TimeFormat = "HH:mm:ss", - Description = "Item 12", - Content = "Content 12123123123123" - }, - new() - { - Time = DateTime.Now, - TimeFormat = "HH:mm:ss", - Description = "Item 13", - Content = "Last" - } }; } diff --git a/demo/Ursa.Demo/Views/MainWindow.axaml b/demo/Ursa.Demo/Views/MainWindow.axaml index 9eb159c..f5cc372 100644 --- a/demo/Ursa.Demo/Views/MainWindow.axaml +++ b/demo/Ursa.Demo/Views/MainWindow.axaml @@ -2,13 +2,17 @@ x:Class="Ursa.Demo.Views.MainWindow" xmlns="https://github.com/avaloniaui" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" + xmlns:converters="clr-namespace:Ursa.Demo.Converters" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:pages="clr-namespace:Ursa.Demo.Pages" + xmlns:u="https://irihi.tech/ursa" xmlns:vm="using:Ursa.Demo.ViewModels" Title="Ursa.Demo" d:DesignHeight="450" d:DesignWidth="800" + x:CompileBindings="True" + x:DataType="vm:MainWindowViewModel" Icon="/Assets/Ursa.ico" mc:Ignorable="d"> @@ -16,44 +20,67 @@ - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + diff --git a/src/Ursa.Themes.Semi/Controls/Navigation.axaml b/src/Ursa.Themes.Semi/Controls/Navigation.axaml index cb5e55c..c635374 100644 --- a/src/Ursa.Themes.Semi/Controls/Navigation.axaml +++ b/src/Ursa.Themes.Semi/Controls/Navigation.axaml @@ -24,57 +24,59 @@ - - - - + + + + + - - - - - - - - - - - - + + + + + + + + + + + + + diff --git a/src/Ursa.Themes.Semi/Themes/Shared/NavigationMenu.axaml b/src/Ursa.Themes.Semi/Themes/Shared/NavigationMenu.axaml index 4ba4cf4..7b8ec35 100644 --- a/src/Ursa.Themes.Semi/Themes/Shared/NavigationMenu.axaml +++ b/src/Ursa.Themes.Semi/Themes/Shared/NavigationMenu.axaml @@ -1,5 +1,7 @@ - + M5 2H19C20.6569 2 22 3.34315 22 5V19C22 20.6569 20.6569 22 19 22H5C3.34315 22 2 20.6569 2 19V5C2 3.34315 3.34315 2 5 2ZM6 4C5.44772 4 5 4.44772 5 5V19C5 19.5523 5.44772 20 6 20H9C9.55229 20 10 19.5523 10 19V5C10 4.44772 9.55229 4 9 4H6Z M4.08045 7.59809C4.66624 7.01231 5.61599 7.01231 6.20177 7.59809L11.8586 13.2549L17.5155 7.59809C18.1013 7.01231 19.051 7.01231 19.6368 7.59809C20.2226 8.18388 20.2226 9.13363 19.6368 9.71941L12.9193 16.4369C12.3335 17.0227 11.3838 17.0227 10.798 16.4369L4.08045 9.71941C3.49467 9.13363 3.49467 8.18388 4.08045 7.59809Z @@ -11,7 +13,7 @@ 24 8 8 - 0 + 0 0 0 @@ -25,7 +27,7 @@ 0,2 8 - 6 + 6 12,0 12,0 8 diff --git a/src/Ursa/Controls/Navigation/NavigationMenuItem.cs b/src/Ursa/Controls/Navigation/NavigationMenuItem.cs index 946af82..d5ce45e 100644 --- a/src/Ursa/Controls/Navigation/NavigationMenuItem.cs +++ b/src/Ursa/Controls/Navigation/NavigationMenuItem.cs @@ -131,7 +131,7 @@ public class NavigationMenuItem: HeaderedSelectingItemsControl if (_rootMenu is not null) { - IsClosed = _rootMenu.IsClosed; + // IsClosed = _rootMenu.IsClosed; } _rootMenu?.GetObservable(NavigationMenu.IsClosedProperty) @@ -139,7 +139,7 @@ public class NavigationMenuItem: HeaderedSelectingItemsControl _rootMenu?.UpdateSelectionFromSelectedItem(_rootMenu.SelectedItem); _popup = e.NameScope.Find(PART_Popup); Level = CalculateDistanceFromLogicalParent(this) - 1; - bool isTopLevel = Level == 1; + bool isTopLevel = Level == 0; IsTopLevelMenuItem = isTopLevel; PseudoClasses.Set(PC_TopLevel, isTopLevel); } @@ -165,7 +165,7 @@ public class NavigationMenuItem: HeaderedSelectingItemsControl { if (_rootMenu is not null ) { - object? o = this.DataContext ?? this; + object? o = this.DataContext == _rootMenu.DataContext ? this : this.DataContext ?? this; _rootMenu.SelectedItem = o; } SetSelection(this, true, true); @@ -219,7 +219,7 @@ public class NavigationMenuItem: HeaderedSelectingItemsControl } else { - if (selected) + if (selected && source!=null) { _rootMenu?.UpdateSelection(this); } @@ -262,7 +262,10 @@ public class NavigationMenuItem: HeaderedSelectingItemsControl while (logical != null && !(logical is T)) { - ++result; + if (logical is NavigationMenuItem) + { + result++; + } logical = logical.LogicalParent; } diff --git a/src/Ursa/Controls/TagInput/TagInput.cs b/src/Ursa/Controls/TagInput/TagInput.cs index 5ee089b..f0f0c69 100644 --- a/src/Ursa/Controls/TagInput/TagInput.cs +++ b/src/Ursa/Controls/TagInput/TagInput.cs @@ -1,5 +1,6 @@ using System.Collections; using System.Collections.ObjectModel; +using System.Collections.Specialized; using Avalonia; using Avalonia.Collections; using Avalonia.Controls; @@ -128,7 +129,7 @@ public class TagInput : TemplatedControl private void OnInputThemePropertyChanged(AvaloniaPropertyChangedEventArgs args) { var newTheme = args.GetNewValue(); - if (newTheme.TargetType == typeof(TextBox)) + if (newTheme?.TargetType == typeof(TextBox)) { _textBox.Theme = newTheme; } @@ -137,6 +138,7 @@ public class TagInput : TemplatedControl private void OnTagsPropertyChanged(AvaloniaPropertyChangedEventArgs args) { var newTags = args.GetNewValue>(); + var oldTags = args.GetOldValue>(); for (int i = 0; i < Items.Count - 1; i++) { Items.RemoveAt(Items.Count - 1); @@ -146,6 +148,46 @@ public class TagInput : TemplatedControl { Items.Insert(Items.Count - 1, newTags[i]); } + + if (oldTags is INotifyCollectionChanged inccold) + { + inccold.CollectionChanged-= OnCollectionChanged; + } + + if (Tags is INotifyCollectionChanged incc) + { + incc.CollectionChanged += OnCollectionChanged; + } + } + + private void OnCollectionChanged(object sender, NotifyCollectionChangedEventArgs e) + { + if (e.Action == NotifyCollectionChangedAction.Add) + { + var items = e.NewItems; + int index = e.NewStartingIndex; + foreach (var item in items) + { + if (item is string s) + { + Items.Insert(index, s); + index++; + } + } + } + else if (e.Action == NotifyCollectionChangedAction.Remove) + { + var items = e.OldItems; + int index = e.OldStartingIndex; + foreach (var item in items) + { + if (item is string s) + { + Items.RemoveAt(index); + } + } + } + } private void OnTextBoxKeyDown(object? sender, KeyEventArgs args) @@ -173,7 +215,7 @@ public class TagInput : TemplatedControl for (int i = 0; i < values.Length; i++) { int index = Items.Count - 1; - Items.Insert(index, values[i]); + // Items.Insert(index, values[i]); Tags.Insert(index, values[i]); } @@ -189,7 +231,7 @@ public class TagInput : TemplatedControl return; } int index = Items.Count - 2; - Items.RemoveAt(index); + // Items.RemoveAt(index); Tags.RemoveAt(index); } } @@ -204,7 +246,7 @@ public class TagInput : TemplatedControl int? index = _itemsControl?.IndexFromContainer(presenter); if (index is >= 0 && index < Items.Count - 1) { - Items.RemoveAt(index.Value); + // Items.RemoveAt(index.Value); Tags.RemoveAt(index.Value); } }