make a behavior for the acb
ADD
WalletWasabi.Fluent/Behaviors/TagBoxAutoCompleteBoxBehavior.cs
+using Avalonia;
+using Avalonia.Controls;
+using Avalonia.Xaml.Interactivity;
+using System;
+using System.Reactive.Disposables;
+using System.Reactive.Linq;
+using Avalonia.Input;
+using Avalonia.Threading;
+using ReactiveUI;
+
+namespace WalletWasabi.Fluent.Behaviors
+{
+ public class TagBoxAutoCompleteBoxBehavior : Behavior<AutoCompleteBox>
+ {
+ private int _lastSelectedIndex;
+ public static readonly StyledProperty<Action> EnterKeyOrSpacePressedActionProperty =
+ AvaloniaProperty.Register<SplitViewAutoBehavior, Action>(nameof(EnterKeyOrSpacePressedAction));
+
+ public static readonly StyledProperty<Action> BackspaceAndEmptyTextActionProperty =
+ AvaloniaProperty.Register<SplitViewAutoBehavior, Action>(nameof(BackspaceAndEmptyTextAction));
+
+ public Action EnterKeyOrSpacePressedAction
+ {
+ get => GetValue(EnterKeyOrSpacePressedActionProperty);
+ set => SetValue(EnterKeyOrSpacePressedActionProperty, value);
+ }
+
+ public Action BackspaceAndEmptyTextAction
+ {
+ get => GetValue(BackspaceAndEmptyTextActionProperty);
+ set => SetValue(BackspaceAndEmptyTextActionProperty, value);
+ }
+
+ protected override void OnAttached()
+ {
+ AssociatedObject.KeyUp += OnKeyUp;
+ AssociatedObject.TextChanged += OnTextChanged;
+
+ Dispatcher.UIThread.InvokeAsync(() =>
+ {
+ // Refocus because the old control is destroyed
+ // when the tag list changes.
+ AssociatedObject.Focus();
+ });
+
+
+ base.OnAttached();
+ }
+
+ private void OnTextChanged(object? sender, EventArgs e)
+ {
+ var obj = AssociatedObject?.Text ?? "";
+
+ if (obj.Length > 1 && !string.IsNullOrEmpty(obj.Trim()) && obj.EndsWith(' '))
+ {
+ EnterKeyOrSpacePressedAction?.Invoke();
+ Dispatcher.UIThread.InvokeAsync(() => { AssociatedObject.Text = ""; });
+ }
+ }
+
+ private void OnKeyUp(object? sender, KeyEventArgs e)
+ {
+ if (e.Key == Key.Back && AssociatedObject?.Text.Length == 0)
+ {
+ BackspaceAndEmptyTextAction?.Invoke();
+ }
+ else if (e.Key == Key.Enter && !string.IsNullOrEmpty(AssociatedObject?.Text.Trim() ?? ""))
+ {
+ EnterKeyOrSpacePressedAction?.Invoke();
+ Dispatcher.UIThread.InvokeAsync(() => { AssociatedObject.Text = ""; });
+ }
+ }
+
+ protected override void OnDetaching()
+ {
+ base.OnDetaching();
+
+ AssociatedObject.KeyUp -= OnKeyUp;
+ }
+ }
+}
\ No newline at end of file

MODIFY
WalletWasabi.Fluent/ViewModels/TagsBox/TagBoxViewModel.cs
WalletWasabi.Fluent/ViewModels/TagsBox/TagBoxViewModel.cs
@@ -50,9 +50,9 @@ namespace WalletWasabi.Fluent.ViewModels.TagsBox
set => this.RaiseAndSetIfChanged(ref _tags, value);
}
- public void AddTag()
+ public void AddTag(string tagString)
{
- Tags.Add(new TagViewModel(this, "Test"));
+ Tags.Add(new TagViewModel(this, tagString));
}
public void RemoveTag()

MODIFY
WalletWasabi.Fluent/ViewModels/TagsBox/TagInputViewModel.cs
WalletWasabi.Fluent/ViewModels/TagsBox/TagInputViewModel.cs
+using System;
using System.Collections;
+using AvalonStudio.MVVM;
using ReactiveUI;
using WalletWasabi.Gui.ViewModels;
@@ -9,13 +11,30 @@ namespace WalletWasabi.Fluent.ViewModels.TagsBox
private readonly ObservableAsPropertyHelper<IEnumerable> _suggestions;
private string _inputText;
+ private Action _EnterKeyOrSpacePressedAction;
+ private Action _backspaceAndEmptyTextAction;
+ private TagBoxViewModel _parent;
public IEnumerable Suggestions => _suggestions.Value;
public TagInputViewModel(TagBoxViewModel parent)
{
- _suggestions = parent.WhenAnyValue(x => x.Suggestions)
+ _parent = parent;
+ _suggestions = _parent.WhenAnyValue(x => x.Suggestions)
.ToProperty(this, x => x.Suggestions);
+
+ this.EnterKeyOrSpacePressedAction += OnEnterKeyOrSpacePressedAction;
+ this.BackspaceAndEmptyTextAction += OnBackspaceAndEmptyTextAction;
+ }
+
+ private void OnBackspaceAndEmptyTextAction()
+ {
+ _parent.RemoveTag();
+ }
+
+ private void OnEnterKeyOrSpacePressedAction()
+ {
+ _parent.AddTag(InputText.Trim());
}
public string InputText
@@ -23,5 +42,17 @@ namespace WalletWasabi.Fluent.ViewModels.TagsBox
get => _inputText;
set => this.RaiseAndSetIfChanged(ref _inputText, value);
}
+
+ public Action EnterKeyOrSpacePressedAction
+ {
+ get => _EnterKeyOrSpacePressedAction;
+ set => this.RaiseAndSetIfChanged(ref _EnterKeyOrSpacePressedAction, value);
+ }
+
+ public Action BackspaceAndEmptyTextAction
+ {
+ get => _backspaceAndEmptyTextAction;
+ set => this.RaiseAndSetIfChanged(ref _backspaceAndEmptyTextAction, value);
+ }
}
}
\ No newline at end of file

MODIFY
WalletWasabi.Fluent/Views/TagsBox/TagInputView.xaml
WalletWasabi.Fluent/Views/TagsBox/TagInputView.xaml
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:c="clr-namespace:WalletWasabi.Fluent.Views.TagsBox"
mc:Ignorable="d"
+ xmlns:i="clr-namespace:Avalonia.Xaml.Interactivity;assembly=Avalonia.Xaml.Interactivity"
+ xmlns:behaviors="clr-namespace:WalletWasabi.Fluent.Behaviors;assembly=WalletWasabi.Fluent"
x:Class="WalletWasabi.Fluent.Views.TagsBox.TagInputView">
- <AutoCompleteBox Text="{Binding InputText, Mode=TwoWay}" Items="{Binding Suggestions}"/>
+ <AutoCompleteBox Text="{Binding InputText, Mode=TwoWay}" Items="{Binding Suggestions}">
+ <i:Interaction.Behaviors>
+ <behaviors:TagBoxAutoCompleteBoxBehavior
+ EnterKeyOrSpacePressedAction="{Binding EnterKeyOrSpacePressedAction, Mode=TwoWay}"
+ BackspaceAndEmptyTextAction="{Binding BackspaceAndEmptyTextAction, Mode=TwoWay}" />
+ </i:Interaction.Behaviors>
+ </AutoCompleteBox>
</UserControl>
\ No newline at end of file

make a behavior for the acb