Skip to content

Commit 162fed1

Browse files
Add add/remove/edit/moveup/movedown code
1 parent 49e9a41 commit 162fed1

File tree

2 files changed

+161
-38
lines changed

2 files changed

+161
-38
lines changed

WatchOnlyBitcoinWallet/MainWindow.axaml

Lines changed: 11 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@
3434

3535
<Grid RowDefinitions="auto,*,auto">
3636

37-
<Menu Background="LightGray" Grid.Row="0">
37+
<Menu Background="GhostWhite" Grid.Row="0">
3838
<MenuItem Header="_Options">
3939
<MenuItem Header="_Settings"
4040
InputGesture="F2"
@@ -105,7 +105,11 @@
105105
</TextBlock>
106106
</Grid>
107107

108-
<ListBox ItemsSource="{Binding AddressList}" Margin="3" Grid.Column="1">
108+
<ListBox ItemsSource="{Binding AddressList}"
109+
SelectedItem="{Binding SelectedAddress}"
110+
SelectedIndex="{Binding SelectedIndex}"
111+
Margin="3" Grid.Column="1">
112+
109113
<ListBox.Template>
110114
<ControlTemplate>
111115
<DockPanel LastChildFill="True">
@@ -143,19 +147,19 @@
143147
</Style>
144148
</StackPanel.Styles>
145149

146-
<Button ToolTip.Tip="Add New">
150+
<Button ToolTip.Tip="Add New" Command="{Binding AddCommand}">
147151
<Image Source="/Assets/Add.png"/>
148152
</Button>
149-
<Button ToolTip.Tip="Remove Selected">
153+
<Button ToolTip.Tip="Remove Selected" Command="{Binding RemoveCommand}">
150154
<Image Source="/Assets/Remove.png"/>
151155
</Button>
152-
<Button ToolTip.Tip="Edit Selected">
156+
<Button ToolTip.Tip="Edit Selected" Command="{Binding EditCommand}">
153157
<Image Source="/Assets/Edit.png"/>
154158
</Button>
155-
<Button ToolTip.Tip="Move Up">
159+
<Button ToolTip.Tip="Move Up" Command="{Binding MoveUpCommand}">
156160
<Image Source="/Assets/MoveUp.png"/>
157161
</Button>
158-
<Button ToolTip.Tip="Move Down">
162+
<Button ToolTip.Tip="Move Down" Command="{Binding MoveDownCommand}">
159163
<Image Source="/Assets/MoveDown.png"/>
160164
</Button>
161165
</StackPanel>

WatchOnlyBitcoinWallet/ViewModels/MainWindowViewModel.cs

Lines changed: 150 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -5,11 +5,11 @@
55

66
using Avalonia.Input.Platform;
77
using System;
8-
using System.Collections.Generic;
98
using System.Collections.ObjectModel;
10-
using System.ComponentModel;
9+
using System.Diagnostics;
1110
using System.Linq;
1211
using System.Reflection;
12+
using System.Threading.Tasks;
1313
using WatchOnlyBitcoinWallet.Models;
1414
using WatchOnlyBitcoinWallet.MVVM;
1515
using WatchOnlyBitcoinWallet.Services;
@@ -24,9 +24,7 @@ public MainWindowViewModel()
2424
WindowMan = new WindowManager();
2525
FileMan = new FileManager();
2626

27-
AddressList = new BindingList<BitcoinAddress>(FileMan.ReadWalletFile());
28-
AddressList.ListChanged += AddressList_ListChanged;
29-
27+
AddressList = new(FileMan.ReadWalletFile());
3028
SettingsInstance = FileMan.ReadSettingsFile();
3129

3230
GetBalanceCommand = new BindableCommand(GetBalance, () => !IsReceiving);
@@ -37,37 +35,53 @@ public MainWindowViewModel()
3735
ImportFromTextCommand = new BindableCommand(ImportFromText);
3836
ImportFromFileCommand = new BindableCommand(ImportFromFile);
3937

38+
AddCommand = new(Add);
39+
RemoveCommand = new(Remove, () => SelectedAddress is not null);
40+
EditCommand = new(Edit, () => SelectedAddress is not null);
41+
MoveUpCommand = new(MoveUp, () => SelectedIndex > 0);
42+
MoveDownCommand = new(MoveDown, () => SelectedIndex >= 0 && SelectedIndex < AddressList.Count - 1);
43+
4044
Version ver = Assembly.GetExecutingAssembly().GetName().Version ?? new Version();
4145
VersionString = string.Format("Version {0}.{1}.{2}", ver.Major, ver.Minor, ver.Build);
4246
}
4347

4448

4549

46-
void AddressList_ListChanged(object sender, ListChangedEventArgs e)
50+
public ObservableCollection<BitcoinAddress> AddressList { get; set; }
51+
52+
private BitcoinAddress? _selAddr;
53+
public BitcoinAddress? SelectedAddress
4754
{
48-
if (e.ListChangedType == ListChangedType.ItemChanged)
55+
get => _selAddr;
56+
set
4957
{
50-
BitcoinAddress addr = ((BindingList<BitcoinAddress>)sender)[e.NewIndex];
51-
if (addr.Address != null)
52-
{
53-
addr.Validate(addr.Address);
54-
}
55-
if (!addr.HasErrors)
58+
if (SetField(ref _selAddr, value))
5659
{
57-
DataManager.WriteFile(AddressList, DataManager.FileType.Wallet);
60+
RemoveCommand.RaiseCanExecuteChanged();
61+
EditCommand.RaiseCanExecuteChanged();
5862
}
5963
}
60-
else if (e.ListChangedType == ListChangedType.ItemDeleted || e.ListChangedType == ListChangedType.ItemAdded)
64+
}
65+
66+
private int _selIndex = -1;
67+
public int SelectedIndex
68+
{
69+
get => _selIndex;
70+
set
6171
{
62-
DataManager.WriteFile(AddressList, DataManager.FileType.Wallet);
72+
if (SetField(ref _selIndex, value))
73+
{
74+
MoveUpCommand.RaiseCanExecuteChanged();
75+
MoveDownCommand.RaiseCanExecuteChanged();
76+
}
6377
}
6478
}
6579

66-
67-
public IWindowManager WindowMan { get; set; }
6880
public IClipboard Clipboard { get; set; }
6981
public IFileManager FileMan { get; set; }
70-
82+
public IWindowManager WindowMan { get; set; }
83+
public SettingsModel SettingsInstance { get; }
84+
public string VersionString { get; }
7185

7286
/// <summary>
7387
/// Indicating an active connection.
@@ -86,18 +100,6 @@ public bool IsReceiving
86100
}
87101
private bool isReceiving;
88102

89-
public string VersionString { get; private set; }
90-
91-
92-
public BindingList<BitcoinAddress> AddressList { get; set; }
93-
94-
95-
private SettingsModel settingsInstance;
96-
public SettingsModel SettingsInstance
97-
{
98-
get { return settingsInstance; }
99-
set { SetField(ref settingsInstance, value); }
100-
}
101103

102104
public decimal BitcoinBalance
103105
{
@@ -126,6 +128,36 @@ public decimal BitcoinBalanceLC
126128
}
127129

128130

131+
private void SaveWallet()
132+
{
133+
FileMan.WriteWallet(AddressList.ToList());
134+
}
135+
136+
private readonly object lockObj = new();
137+
private bool isSavePending = false;
138+
private async void QueueSaveWallet()
139+
{
140+
lock (lockObj)
141+
{
142+
if (isSavePending)
143+
{
144+
return;
145+
}
146+
else
147+
{
148+
isSavePending = true;
149+
}
150+
}
151+
152+
await Task.Delay(TimeSpan.FromSeconds(10));
153+
lock (lockObj)
154+
{
155+
SaveWallet();
156+
isSavePending = false;
157+
}
158+
}
159+
160+
129161
public BindableCommand OpenAboutCommand { get; private set; }
130162
private async void OpenAbout()
131163
{
@@ -255,5 +287,92 @@ private async void GetBalance()
255287
IsReceiving = false;
256288
}
257289

290+
291+
public BindableCommand AddCommand { get; }
292+
public async void Add()
293+
{
294+
AddEditViewModel vm = new();
295+
await WindowMan.ShowDialog(vm);
296+
if (vm.IsChanged)
297+
{
298+
BitcoinAddress t = new()
299+
{
300+
Address = vm.AddressString,
301+
Name = vm.Tag
302+
};
303+
AddressList.Add(t);
304+
SaveWallet();
305+
}
306+
}
307+
308+
public BindableCommand RemoveCommand { get; }
309+
private void Remove()
310+
{
311+
if (SelectedAddress is not null)
312+
{
313+
AddressList.Remove(SelectedAddress);
314+
SaveWallet();
315+
}
316+
else
317+
{
318+
Errors = "Nothing is selected!";
319+
}
320+
}
321+
322+
public BindableCommand EditCommand { get; }
323+
public async void Edit()
324+
{
325+
if (SelectedAddress is not null)
326+
{
327+
AddEditViewModel vm = new()
328+
{
329+
AddressString = SelectedAddress.Address,
330+
Tag = SelectedAddress.Name
331+
};
332+
333+
await WindowMan.ShowDialog(vm);
334+
if (vm.IsChanged)
335+
{
336+
SelectedAddress.Address = vm.AddressString;
337+
SelectedAddress.Name = vm.Tag;
338+
339+
SaveWallet();
340+
}
341+
}
342+
else
343+
{
344+
Errors = "Nothing is selected!";
345+
}
346+
}
347+
348+
public BindableCommand MoveUpCommand { get; }
349+
private void MoveUp()
350+
{
351+
Debug.Assert(SelectedIndex != -1); // selected is not null
352+
Debug.Assert(SelectedIndex != 0); // selected is not first item
353+
354+
// When items are swapped, the selected item turns into null so SelectedIndex value will turn into -1.
355+
// Store it here to use later when setting the new selected item
356+
int i = SelectedIndex;
357+
(AddressList[i - 1], AddressList[i]) = (AddressList[i], AddressList[i - 1]);
358+
SelectedAddress = AddressList[i - 1];
359+
360+
QueueSaveWallet();
361+
}
362+
363+
public BindableCommand MoveDownCommand { get; }
364+
private void MoveDown()
365+
{
366+
Debug.Assert(SelectedIndex != -1); // selected is not null
367+
Debug.Assert(SelectedIndex != AddressList.Count - 1); // selected is not last item
368+
369+
// When items are swapped, the selected item turns into null so SelectedIndex value will turn into -1.
370+
// Store it here to use later when setting the new selected item
371+
int i = SelectedIndex;
372+
(AddressList[i + 1], AddressList[i]) = (AddressList[i], AddressList[i + 1]);
373+
SelectedAddress = AddressList[i + 1];
374+
375+
QueueSaveWallet();
376+
}
258377
}
259378
}

0 commit comments

Comments
 (0)