Use TreeDataGrid for ReceiveAddressesView
MODIFY
WalletWasabi.Fluent/ViewModels/Wallets/Receive/AddressViewModel.cs
WalletWasabi.Fluent/ViewModels/Wallets/Receive/AddressViewModel.cs
@@ -50,4 +50,50 @@ public partial class AddressViewModel : ViewModelBase
public List<string> FilteredLabel { get; }
public List<string> Label { get; }
+
+ public static Comparison<AddressViewModel?> SortAscending<T>(Func<AddressViewModel, T> selector)
+ {
+ return (x, y) =>
+ {
+ if (x is null && y is null)
+ {
+ return 0;
+ }
+ else if (x is null)
+ {
+ return -1;
+ }
+ else if (y is null)
+ {
+ return 1;
+ }
+ else
+ {
+ return Comparer<T>.Default.Compare(selector(x), selector(y));
+ }
+ };
+ }
+
+ public static Comparison<AddressViewModel?> SortDescending<T>(Func<AddressViewModel, T> selector)
+ {
+ return (x, y) =>
+ {
+ if (x is null && y is null)
+ {
+ return 0;
+ }
+ else if (x is null)
+ {
+ return 1;
+ }
+ else if (y is null)
+ {
+ return -1;
+ }
+ else
+ {
+ return Comparer<T>.Default.Compare(selector(y), selector(x));
+ }
+ };
+ }
}

MODIFY
WalletWasabi.Fluent/ViewModels/Wallets/Receive/ReceiveAddressesViewModel.cs
WalletWasabi.Fluent/ViewModels/Wallets/Receive/ReceiveAddressesViewModel.cs
@@ -5,11 +5,15 @@ using System.Reactive.Disposables;
using System.Reactive.Linq;
using System.Threading.Tasks;
using Avalonia;
+using Avalonia.Controls;
+using Avalonia.Controls.Models.TreeDataGrid;
+using Avalonia.Controls.Templates;
using NBitcoin;
using ReactiveUI;
using WalletWasabi.Blockchain.Keys;
using WalletWasabi.Fluent.ViewModels.Dialogs;
using WalletWasabi.Fluent.ViewModels.Navigation;
+using WalletWasabi.Fluent.Views.Wallets.Receive.Columns;
using WalletWasabi.Logging;
using WalletWasabi.Wallets;
@@ -19,9 +23,7 @@ namespace WalletWasabi.Fluent.ViewModels.Wallets.Receive;
public partial class ReceiveAddressesViewModel : RoutableViewModel
{
private readonly HashSet<string> _suggestions;
-
- [AutoNotify] private ObservableCollection<AddressViewModel> _addresses;
- [AutoNotify] private AddressViewModel? _selectedAddress;
+ private ObservableCollection<AddressViewModel> _addresses;
public ReceiveAddressesViewModel(Wallet wallet, HashSet<string> suggestions)
{
@@ -34,6 +36,54 @@ public partial class ReceiveAddressesViewModel : RoutableViewModel
EnableBack = true;
+ // [Column] [View] [Header] [Width] [MinWidth] [MaxWidth] [CanUserSort]
+ // Actions ActionsColumnView - 90 - - false
+ // Address AddressColumnView Address 2* - - true
+ // Labels LabelsColumnView Labels 210 - - false
+
+ Source = new FlatTreeDataGridSource<AddressViewModel>(_addresses)
+ {
+ Columns =
+ {
+ // Actions
+ new TemplateColumn<AddressViewModel>(
+ "Labels",
+ new FuncDataTemplate<AddressViewModel>((node, ns) => new ActionsColumnView(), true),
+ options: new ColumnOptions<AddressViewModel>
+ {
+ CanUserResizeColumn = false,
+ CanUserSortColumn = false
+ },
+ width: new GridLength(90, GridUnitType.Pixel)),
+
+ // Address
+ new TemplateColumn<AddressViewModel>(
+ "Labels",
+ new FuncDataTemplate<AddressViewModel>((node, ns) => new AddressColumnView(), true),
+ options: new ColumnOptions<AddressViewModel>
+ {
+ CanUserResizeColumn = false,
+ CanUserSortColumn = true,
+ CompareAscending = AddressViewModel.SortAscending(x => x.Address),
+ CompareDescending = AddressViewModel.SortDescending(x => x.Address)
+ },
+ width: new GridLength(2, GridUnitType.Star)),
+
+ // Labels
+ new TemplateColumn<AddressViewModel>(
+ "Labels",
+ new FuncDataTemplate<AddressViewModel>((node, ns) => new LabelsColumnView(), true),
+ options: new ColumnOptions<AddressViewModel>
+ {
+ CanUserResizeColumn = false,
+ CanUserSortColumn = false
+ },
+ width: new GridLength(210, GridUnitType.Pixel))
+ }
+ };
+
+ Source.RowSelection!.SingleSelect = true;
+
InitializeAddresses();
}
@@ -41,6 +91,8 @@ public partial class ReceiveAddressesViewModel : RoutableViewModel
public Network Network { get; }
+ public FlatTreeDataGridSource<AddressViewModel> Source { get; }
+
protected override void OnNavigatedTo(bool isInHistory, CompositeDisposable disposables)
{
base.OnNavigatedTo(isInHistory, disposables);
@@ -56,13 +108,13 @@ public partial class ReceiveAddressesViewModel : RoutableViewModel
{
try
{
- Addresses.Clear();
+ _addresses.Clear();
IEnumerable<HdPubKey> keys = Wallet.KeyManager.GetKeys(x => !x.Label.IsEmpty && !x.IsInternal && x.KeyState == KeyState.Clean).Reverse();
foreach (HdPubKey key in keys)
{
- Addresses.Add(new AddressViewModel(this, Wallet, key, Network));
+ _addresses.Add(new AddressViewModel(this, Wallet, key, Network));
}
}
catch (Exception ex)

MODIFY
WalletWasabi.Fluent/Views/Wallets/Receive/Columns/ActionsColumnView.axaml
WalletWasabi.Fluent/Views/Wallets/Receive/Columns/ActionsColumnView.axaml
xmlns:c="using:WalletWasabi.Fluent.Controls"
xmlns:receive="clr-namespace:WalletWasabi.Fluent.ViewModels.Wallets.Receive"
mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="450"
- x:DataType="receive:ReceiveAddressesViewModel"
+ x:DataType="receive:AddressViewModel"
x:CompileBindings="True"
x:Class="WalletWasabi.Fluent.Views.Wallets.Receive.Columns.ActionsColumnView">
<Panel>

MODIFY
WalletWasabi.Fluent/Views/Wallets/Receive/Columns/AddressColumnView.axaml
WalletWasabi.Fluent/Views/Wallets/Receive/Columns/AddressColumnView.axaml
xmlns:c="using:WalletWasabi.Fluent.Controls"
xmlns:receive="clr-namespace:WalletWasabi.Fluent.ViewModels.Wallets.Receive"
mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="450"
- x:DataType="receive:ReceiveAddressesViewModel"
+ x:DataType="receive:AddressViewModel"
x:CompileBindings="True"
x:Class="WalletWasabi.Fluent.Views.Wallets.Receive.Columns.AddressColumnView">
<DockPanel LastChildFill="True" Margin="10 0" x:DataType="receive:AddressViewModel">

MODIFY
WalletWasabi.Fluent/Views/Wallets/Receive/Columns/LabelsColumnView.axaml
WalletWasabi.Fluent/Views/Wallets/Receive/Columns/LabelsColumnView.axaml
xmlns:c="using:WalletWasabi.Fluent.Controls"
xmlns:receive="clr-namespace:WalletWasabi.Fluent.ViewModels.Wallets.Receive"
mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="450"
- x:DataType="receive:ReceiveAddressesViewModel"
+ x:DataType="receive:AddressViewModel"
x:CompileBindings="True"
x:Class="WalletWasabi.Fluent.Views.Wallets.Receive.Columns.LabelsColumnView">
<DockPanel LastChildFill="True" Margin="10 0 30 0" x:DataType="receive:AddressViewModel">

MODIFY
WalletWasabi.Fluent/Views/Wallets/Receive/ReceiveAddressesView.axaml
WalletWasabi.Fluent/Views/Wallets/Receive/ReceiveAddressesView.axaml
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:c="using:WalletWasabi.Fluent.Controls"
xmlns:receive="clr-namespace:WalletWasabi.Fluent.ViewModels.Wallets.Receive"
- xmlns:columns="clr-namespace:WalletWasabi.Fluent.Views.Wallets.Receive.Columns"
mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="450"
x:DataType="receive:ReceiveAddressesViewModel"
x:CompileBindings="True"
EnableCancel="{Binding EnableCancel}"
EnableBack="{Binding EnableBack}"
ScrollViewer.VerticalScrollBarVisibility="Disabled">
- <DataBox Items="{Binding Addresses}"
+ <TreeDataGrid Source="{Binding Source}"
CanUserSortColumns="True">
- <DataBox.Styles>
+ <TreeDataGrid.Styles>
<Style Selector="c|AnimatedButton.addressActionButton">
<Setter Property="DockPanel.Dock" Value="Right" />
<Setter Property="Margin" Value="5 0 0 0" />
<Setter Property="Height" Value="15" />
<Setter Property="Foreground" Value="{DynamicResource SystemAccentColor}" />
</Style>
- </DataBox.Styles>
- <DataBox.Columns>
- <DataBoxTemplateColumn Width="90"
- CanUserSort="False">
- <DataBoxTemplateColumn.CellTemplate>
- <DataTemplate>
- <columns:ActionsColumnView />
- </DataTemplate>
- </DataBoxTemplateColumn.CellTemplate>
- </DataBoxTemplateColumn>
-
- <DataBoxTemplateColumn Header="Address"
- Width="2*"
- CanUserSort="True">
- <DataBoxTemplateColumn.CellTemplate>
- <DataTemplate>
- <columns:AddressColumnView />
- </DataTemplate>
- </DataBoxTemplateColumn.CellTemplate>
- </DataBoxTemplateColumn>
-
- <DataBoxTemplateColumn Header="Labels"
- Width="210"
- CanUserSort="True">
- <DataBoxTemplateColumn.CellTemplate>
- <DataTemplate>
- <columns:LabelsColumnView />
- </DataTemplate>
- </DataBoxTemplateColumn.CellTemplate>
- </DataBoxTemplateColumn>
- </DataBox.Columns>
- </DataBox>
+ </TreeDataGrid.Styles>
+ </TreeDataGrid>
</c:ContentArea>
</UserControl>
\ No newline at end of file

Use TreeDataGrid for ReceiveAddressesView