Move SuggestionLabelsView into TagsBox control template
MODIFY
WalletWasabi.Fluent/Controls/TagsBox.axaml
WalletWasabi.Fluent/Controls/TagsBox.axaml
<Setter Property="Template">
<ControlTemplate>
<DataValidationErrors>
+ <DockPanel x:Name="PART_DockPanel">
+ <ItemsControl Items="{TemplateBinding TopItems}"
+ IsVisible="{TemplateBinding TopItems, Converter={x:Static ObjectConverters.IsNotNull}}"
+ ClipToBounds="False"
+ Margin="0,10,0,0"
+ DockPanel.Dock="Bottom">
+ <ItemsControl.ItemsPanel>
+ <ItemsPanelTemplate>
+ <WrapPanel Orientation="Horizontal" />
+ </ItemsPanelTemplate>
+ </ItemsControl.ItemsPanel>
+ <ItemsControl.ItemTemplate>
+ <DataTemplate>
+ <Button Classes="activeHyperLink"
+ Margin="0,0,6,0"
+ Focusable="False"
+ Content="{Binding}"
+ Command="{Binding #PART_DockPanel.TemplatedParent.AddTag}"
+ CommandParameter="{Binding }"
+ x:CompileBindings="False"/>
+ </DataTemplate>
+ </ItemsControl.ItemTemplate>
+ </ItemsControl>
<Border x:Name="PART_Border" Background="{TemplateBinding Background}"
BorderBrush="{TemplateBinding BorderBrush}"
BorderThickness="{TemplateBinding BorderThickness}"
<c:ConcatenatingWrapPanel Focusable="False" VerticalAlignment="Center">
<c:ConcatenatingWrapPanel.ConcatenatedChildren>
<AutoCompleteBox x:Name="PART_AutoCompleteBox"
- Items="{Binding #PART_Border.TemplatedParent.Suggestions}" />
+ Items="{Binding #PART_DockPanel.TemplatedParent.Suggestions}" />
</c:ConcatenatingWrapPanel.ConcatenatedChildren>
</c:ConcatenatingWrapPanel>
</ItemsPanelTemplate>
</ItemsPresenter>
</Panel>
</Border>
+ </DockPanel>
</DataValidationErrors>
</ControlTemplate>
</Setter>

MODIFY
WalletWasabi.Fluent/Controls/TagsBox.axaml.cs
WalletWasabi.Fluent/Controls/TagsBox.axaml.cs
@@ -45,6 +45,11 @@ namespace WalletWasabi.Fluent.Controls
(o, v) => o.Items = v,
enableDataValidation: true);
+ public static readonly DirectProperty<TagsBox, IEnumerable<string>?> TopItemsProperty =
+ AvaloniaProperty.RegisterDirect<TagsBox, IEnumerable<string>?>(nameof(TopItems),
+ o => o.TopItems,
+ (o, v) => o.TopItems = v);
+
public static readonly DirectProperty<TagsBox, IEnumerable?> SuggestionsProperty =
AvaloniaProperty.RegisterDirect<TagsBox, IEnumerable?>(
nameof(Suggestions),
@@ -62,6 +67,7 @@ namespace WalletWasabi.Fluent.Controls
private IEnumerable? _suggestions;
private ICommand? _completedCommand;
private IEnumerable<string>? _items;
+ private IEnumerable<string>? _topItems;
public static readonly DirectProperty<TagsBox, ICommand?> CompletedCommandProperty =
AvaloniaProperty.RegisterDirect<TagsBox, ICommand?>(
@@ -72,9 +78,6 @@ namespace WalletWasabi.Fluent.Controls
public static readonly StyledProperty<bool> IsReadOnlyProperty =
AvaloniaProperty.Register<TagsBox, bool>(nameof(IsReadOnly));
- public static readonly StyledProperty<Action<Action<string>>?> SetAddTagActionProperty =
- AvaloniaProperty.Register<TagsBox, Action<Action<string>>?>(nameof(SetAddTagAction));
-
[Content]
public IEnumerable<string>? Items
{
@@ -82,6 +85,12 @@ namespace WalletWasabi.Fluent.Controls
set => SetAndRaise(ItemsProperty, ref _items, value);
}
+ public IEnumerable<string>? TopItems
+ {
+ get => _topItems;
+ set => SetAndRaise(TopItemsProperty, ref _topItems, value);
+ }
+
public string Watermark
{
get => GetValue(WatermarkProperty);
@@ -136,12 +145,6 @@ namespace WalletWasabi.Fluent.Controls
set => SetValue(AllowDuplicationProperty, value);
}
- public Action<Action<string>>? SetAddTagAction
- {
- get => GetValue(SetAddTagActionProperty);
- set => SetValue(SetAddTagActionProperty, value);
- }
-
protected override void OnApplyTemplate(TemplateAppliedEventArgs e)
{
base.OnApplyTemplate(e);
@@ -465,10 +468,6 @@ namespace WalletWasabi.Fluent.Controls
? StringComparison.CurrentCulture
: StringComparison.CurrentCultureIgnoreCase;
}
- else if (e.Property == SetAddTagActionProperty)
- {
- SetAddTagAction?.Invoke(AddTag);
- }
}
internal void RemoveTargetTag(object? tag)

MODIFY
WalletWasabi.Fluent/ViewModels/Wallets/Labels/SuggestionLabelsViewModel.cs
WalletWasabi.Fluent/ViewModels/Wallets/Labels/SuggestionLabelsViewModel.cs
@@ -13,18 +13,18 @@ namespace WalletWasabi.Fluent.ViewModels.Wallets.Labels
{
public partial class SuggestionLabelsViewModel
{
- private readonly SourceList<SuggestionLabelViewModel> _suggestionLabels;
- private readonly ObservableCollectionExtended<SuggestionLabelViewModel> _topSuggestions;
+ private readonly SourceList<SuggestionLabelViewModel> _sourceLabels;
+ private readonly ObservableCollectionExtended<string> _topSuggestions;
private readonly ObservableCollectionExtended<string> _suggestions;
private readonly ObservableCollectionExtended<string> _labels;
private Action<string>? _addTag;
public SuggestionLabelsViewModel(int topSuggestionsCount)
{
- _labels = new ObservableCollectionExtended<string>();
- _suggestionLabels = new SourceList<SuggestionLabelViewModel>();
- _topSuggestions = new ObservableCollectionExtended<SuggestionLabelViewModel>();
+ _sourceLabels = new SourceList<SuggestionLabelViewModel>();
+ _topSuggestions = new ObservableCollectionExtended<string>();
_suggestions = new ObservableCollectionExtended<string>();
+ _labels = new ObservableCollectionExtended<string>();
UpdateLabels();
CreateSuggestions(topSuggestionsCount);
@@ -32,7 +32,7 @@ namespace WalletWasabi.Fluent.ViewModels.Wallets.Labels
SetAddTag = (addTag) => _addTag = addTag;
}
- public ObservableCollection<SuggestionLabelViewModel> TopSuggestions => _topSuggestions;
+ public ObservableCollection<string> TopSuggestions => _topSuggestions;
public ObservableCollection<string> Suggestions => _suggestions;
@@ -53,8 +53,8 @@ namespace WalletWasabi.Fluent.ViewModels.Wallets.Labels
.OrderByDescending(x => x.Count)
.ToList();
- _suggestionLabels.Clear();
- _suggestionLabels.AddRange(
+ _sourceLabels.Clear();
+ _sourceLabels.AddRange(
mostUsedLabels.Select(x => new SuggestionLabelViewModel(x.Label, x.Count, label => _addTag?.Invoke(label))));
}
@@ -64,16 +64,17 @@ namespace WalletWasabi.Fluent.ViewModels.Wallets.Labels
.Merge(Observable.FromEventPattern(Labels, nameof(Labels.CollectionChanged)).Select(_ => Unit.Default))
.Select(_ => SuggestionLabelsFilter());
- _suggestionLabels
+ _sourceLabels
.Connect()
.Filter(suggestionLabelsFilter)
.Sort(SortExpressionComparer<SuggestionLabelViewModel>.Descending(x => x.Count))
.Top(topSuggestionsCount)
+ .Transform(x => x.Label)
.ObserveOn(RxApp.MainThreadScheduler)
.Bind(_topSuggestions)
.Subscribe();
- _suggestionLabels
+ _sourceLabels
.Connect()
.Filter(suggestionLabelsFilter)
.Sort(SortExpressionComparer<SuggestionLabelViewModel>.Descending(x => x.Count))

DELETE
WalletWasabi.Fluent/Views/Wallets/Labels/SuggestionLabelsView.axaml
-<UserControl xmlns="https://github.com/avaloniaui"
- xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
- xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
- xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
- mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="450"
- xmlns:labels="clr-namespace:WalletWasabi.Fluent.ViewModels.Wallets.Labels"
- x:DataType="labels:SuggestionLabelsViewModel"
- x:CompileBindings="True"
- x:Class="WalletWasabi.Fluent.Views.Wallets.Labels.SuggestionLabelsView">
- <ItemsControl Items="{Binding TopSuggestions}"
- ClipToBounds="False">
- <ItemsControl.ItemsPanel>
- <ItemsPanelTemplate>
- <WrapPanel Orientation="Horizontal" />
- </ItemsPanelTemplate>
- </ItemsControl.ItemsPanel>
- <ItemsControl.ItemTemplate>
- <DataTemplate x:DataType="labels:SuggestionLabelViewModel">
- <Button Classes="activeHyperLink"
- Margin="0,0,6,0"
- Focusable="False"
- Content="{Binding Label}"
- Command="{Binding AddTagCommand}"
- CommandParameter="{Binding Label}"
- x:CompileBindings="False"/>
- </DataTemplate>
- </ItemsControl.ItemTemplate>
- </ItemsControl>
-</UserControl>
\ No newline at end of file

DELETE
WalletWasabi.Fluent/Views/Wallets/Labels/SuggestionLabelsView.axaml.cs
-using Avalonia.Controls;
-using Avalonia.Markup.Xaml;
-
-namespace WalletWasabi.Fluent.Views.Wallets.Labels
-{
- public class SuggestionLabelsView : UserControl
- {
- public SuggestionLabelsView()
- {
- InitializeComponent();
- }
-
- private void InitializeComponent()
- {
- AvaloniaXamlLoader.Load(this);
- }
- }
-}

MODIFY
WalletWasabi.Fluent/Views/Wallets/Receive/ReceiveView.axaml
WalletWasabi.Fluent/Views/Wallets/Receive/ReceiveView.axaml
</DockPanel>
<c:TagsBox x:Name="LabelsTbx"
DataContext="{Binding SuggestionLabels}"
- SetAddTagAction="{Binding SetAddTag}"
Items="{Binding Labels}"
+ TopItems="{Binding TopSuggestions}"
TagSeparator=","
SuggestionsAreCaseSensitive="True"
RestrictInputToSuggestions="False"
<behaviors:FocusOnAttachedBehavior />
</i:Interaction.Behaviors>
</c:TagsBox>
- <labels:SuggestionLabelsView DataContext="{Binding SuggestionLabels}"/>
</StackPanel>
</DockPanel>
</c:ContentArea>

MODIFY
WalletWasabi.Fluent/Views/Wallets/Send/SendView.axaml
WalletWasabi.Fluent/Views/Wallets/Send/SendView.axaml
VerticalAlignment="Top"
Margin="0,0,0,10">
<Label DockPanel.Dock="Left" Content="_Labels:" Target="LabelTagBox" />
- <labels:SuggestionLabelsView DockPanel.Dock="Bottom"
- Margin="0,10,0,0"
- DataContext="{Binding SuggestionLabels}"/>
<c:TagsBox x:Name="LabelTagBox"
DataContext="{Binding SuggestionLabels}"
- SetAddTagAction="{Binding SetAddTag}"
VerticalAlignment="Top"
Watermark="{StaticResource LabelsWatermarkText}"
TagSeparator=","
SuggestionsAreCaseSensitive="True"
RestrictInputToSuggestions="False"
Items="{Binding Labels}"
+ TopItems="{Binding TopSuggestions}"
Suggestions="{Binding Suggestions}" />
</DockPanel>
</DockPanel>

Move SuggestionLabelsView into TagsBox control template