diff --git a/Source/LibationUiBase/ReactiveObject.cs b/Source/LibationUiBase/ReactiveObject.cs
index e86ed991..53392311 100644
--- a/Source/LibationUiBase/ReactiveObject.cs
+++ b/Source/LibationUiBase/ReactiveObject.cs
@@ -7,8 +7,14 @@ using System.Runtime.CompilerServices;
#nullable enable
namespace LibationUiBase;
+///
+/// ReactiveObject is the base object for ViewModel classes, and it implements INotifyPropertyChanging
+/// and INotifyPropertyChanged. Additionally
+/// object changes.
+///
public class ReactiveObject : SynchronizeInvoker, INotifyPropertyChanged, INotifyPropertyChanging
{
+ // see also notes in Libation/Source/_ARCHITECTURE NOTES.txt :: MVVM
public event PropertyChangedEventHandler? PropertyChanged;
public event PropertyChangingEventHandler? PropertyChanging;
diff --git a/Source/LibationUiBase/SeriesView/AyceButton.cs b/Source/LibationUiBase/SeriesView/AyceButton.cs
index 263e6773..00fb2403 100644
--- a/Source/LibationUiBase/SeriesView/AyceButton.cs
+++ b/Source/LibationUiBase/SeriesView/AyceButton.cs
@@ -117,7 +117,7 @@ namespace LibationUiBase.SeriesView
}
private void DownloadButton_ButtonEnabled(object sender, EventArgs e)
- => OnPropertyChanged(nameof(Enabled));
+ => RaisePropertyChanged(nameof(Enabled));
public override int CompareTo(object ob)
{
diff --git a/Source/LibationUiBase/SeriesView/SeriesButton.cs b/Source/LibationUiBase/SeriesView/SeriesButton.cs
index 3156c036..94d79f2d 100644
--- a/Source/LibationUiBase/SeriesView/SeriesButton.cs
+++ b/Source/LibationUiBase/SeriesView/SeriesButton.cs
@@ -1,8 +1,6 @@
using AudibleApi.Common;
using DataLayer;
-using Dinah.Core.Threading;
using System;
-using System.ComponentModel;
using System.Threading.Tasks;
namespace LibationUiBase.SeriesView
@@ -10,11 +8,9 @@ namespace LibationUiBase.SeriesView
///
/// base view model for the Series Viewer 'Availability' button column
///
- public abstract class SeriesButton : SynchronizeInvoker, IComparable, INotifyPropertyChanged
+ public abstract class SeriesButton : ReactiveObject, IComparable
{
- public event PropertyChangedEventHandler PropertyChanged;
private bool inLibrary;
-
protected Item Item { get; }
public abstract string DisplayText { get; }
public abstract bool HasButtonAction { get; }
@@ -27,8 +23,8 @@ namespace LibationUiBase.SeriesView
if (inLibrary != value)
{
inLibrary = value;
- OnPropertyChanged(nameof(InLibrary));
- OnPropertyChanged(nameof(DisplayText));
+ RaisePropertyChanged(nameof(InLibrary));
+ RaisePropertyChanged(nameof(DisplayText));
}
}
}
@@ -41,9 +37,6 @@ namespace LibationUiBase.SeriesView
public abstract Task PerformClickAsync(LibraryBook accountBook);
- protected void OnPropertyChanged(string propertyName)
- => Invoke(() => PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName)));
-
public override string ToString() => DisplayText;
public abstract int CompareTo(object ob);
diff --git a/Source/LibationUiBase/SeriesView/SeriesItem.cs b/Source/LibationUiBase/SeriesView/SeriesItem.cs
index 44b451e4..cd7d19e1 100644
--- a/Source/LibationUiBase/SeriesView/SeriesItem.cs
+++ b/Source/LibationUiBase/SeriesView/SeriesItem.cs
@@ -4,7 +4,6 @@ using AudibleApi.Common;
using AudibleUtilities;
using DataLayer;
using Dinah.Core;
-using Dinah.Core.Threading;
using FileLiberator;
using LibationFileManager;
using System.Collections.Generic;
@@ -15,7 +14,7 @@ using System.Threading.Tasks;
namespace LibationUiBase.SeriesView
{
- public class SeriesItem : SynchronizeInvoker, INotifyPropertyChanged
+ public class SeriesItem : ReactiveObject
{
public object Cover { get; private set; }
public SeriesOrder Order { get; }
@@ -23,8 +22,6 @@ namespace LibationUiBase.SeriesView
public SeriesButton Button { get; }
public Item Item { get; }
- public event PropertyChangedEventHandler PropertyChanged;
-
private SeriesItem(Item item, string order, bool inLibrary, bool inWishList)
{
Item = item;
@@ -42,10 +39,7 @@ namespace LibationUiBase.SeriesView
}
private void DownloadButton_PropertyChanged(object sender, PropertyChangedEventArgs e)
- => OnPropertyChanged(nameof(Button));
-
- private void OnPropertyChanged(string propertyName)
- => Invoke(() => PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName)));
+ => RaisePropertyChanged(nameof(Button));
private void LoadCover(string pictureId)
{
@@ -66,7 +60,7 @@ namespace LibationUiBase.SeriesView
{
Cover = BaseUtil.LoadImage(e.Picture, PictureSize._80x80);
PictureStorage.PictureCached -= PictureStorage_PictureCached;
- OnPropertyChanged(nameof(Cover));
+ RaisePropertyChanged(nameof(Cover));
}
}
}
diff --git a/Source/LibationUiBase/SeriesView/WishlistButton.cs b/Source/LibationUiBase/SeriesView/WishlistButton.cs
index fcf4bcb8..8a236165 100644
--- a/Source/LibationUiBase/SeriesView/WishlistButton.cs
+++ b/Source/LibationUiBase/SeriesView/WishlistButton.cs
@@ -22,14 +22,7 @@ namespace LibationUiBase.SeriesView
public override bool Enabled
{
get => instanceEnabled;
- protected set
- {
- if (instanceEnabled != value)
- {
- instanceEnabled = value;
- OnPropertyChanged(nameof(Enabled));
- }
- }
+ protected set => RaiseAndSetIfChanged(ref instanceEnabled, value);
}
private bool InWishList
@@ -40,8 +33,8 @@ namespace LibationUiBase.SeriesView
if (inWishList != value)
{
inWishList = value;
- OnPropertyChanged(nameof(InWishList));
- OnPropertyChanged(nameof(DisplayText));
+ RaisePropertyChanged(nameof(InWishList));
+ RaisePropertyChanged(nameof(DisplayText));
}
}
}
diff --git a/Source/LibationWinForms/Dialogs/BookRecordsDialog.cs b/Source/LibationWinForms/Dialogs/BookRecordsDialog.cs
index a93e652e..2891f7ac 100644
--- a/Source/LibationWinForms/Dialogs/BookRecordsDialog.cs
+++ b/Source/LibationWinForms/Dialogs/BookRecordsDialog.cs
@@ -250,12 +250,12 @@ namespace LibationWinForms.Dialogs
}
}
- private class BookRecordEntry : GridView.AsyncNotifyPropertyChanged
+ private class BookRecordEntry : LibationUiBase.ReactiveObject
{
private const string DateFormat = "yyyy-MM-dd HH\\:mm";
private bool _ischecked;
public IRecord Record { get; }
- public bool IsChecked { get => _ischecked; set { _ischecked = value; NotifyPropertyChanged(); } }
+ public bool IsChecked { get => _ischecked; set => RaiseAndSetIfChanged(ref _ischecked, value); }
public string Type => Record.GetType().Name;
public string Start => formatTimeSpan(Record.Start);
public string Created => Record.Created.ToString(DateFormat);
diff --git a/Source/LibationWinForms/GridView/AsyncNotifyPropertyChanged.cs b/Source/LibationWinForms/GridView/AsyncNotifyPropertyChanged.cs
deleted file mode 100644
index f02dd26e..00000000
--- a/Source/LibationWinForms/GridView/AsyncNotifyPropertyChanged.cs
+++ /dev/null
@@ -1,17 +0,0 @@
-using Dinah.Core.Threading;
-using System.ComponentModel;
-using System.Runtime.CompilerServices;
-
-namespace LibationWinForms.GridView
-{
- public abstract class AsyncNotifyPropertyChanged : SynchronizeInvoker, INotifyPropertyChanged
- {
- // see also notes in Libation/Source/_ARCHITECTURE NOTES.txt :: MVVM
- public event PropertyChangedEventHandler PropertyChanged;
-
- // per standard INotifyPropertyChanged pattern:
- // https://docs.microsoft.com/en-us/dotnet/desktop/wpf/data/how-to-implement-property-change-notification
- public void NotifyPropertyChanged([CallerMemberName] string propertyName = "")
- => this.UIThreadSync(() => PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName)));
- }
-}
diff --git a/Source/LibationWinForms/ProcessQueue/ProcessQueueControl.Designer.cs b/Source/LibationWinForms/ProcessQueue/ProcessQueueControl.Designer.cs
index 85fdb856..b5bf91f5 100644
--- a/Source/LibationWinForms/ProcessQueue/ProcessQueueControl.Designer.cs
+++ b/Source/LibationWinForms/ProcessQueue/ProcessQueueControl.Designer.cs
@@ -40,7 +40,6 @@
this.runningTimeLbl = new System.Windows.Forms.ToolStripStatusLabel();
this.tabControl1 = new System.Windows.Forms.TabControl();
this.tabPage1 = new System.Windows.Forms.TabPage();
- this.panel3 = new System.Windows.Forms.Panel();
this.virtualFlowControl2 = new LibationWinForms.ProcessQueue.VirtualFlowControl();
this.panel1 = new System.Windows.Forms.Panel();
this.label1 = new System.Windows.Forms.Label();
@@ -134,7 +133,6 @@
//
// tabPage1
//
- this.tabPage1.Controls.Add(this.panel3);
this.tabPage1.Controls.Add(this.virtualFlowControl2);
this.tabPage1.Controls.Add(this.panel1);
this.tabPage1.Location = new System.Drawing.Point(4, 24);
@@ -145,14 +143,6 @@
this.tabPage1.Text = "Process Queue";
this.tabPage1.UseVisualStyleBackColor = true;
//
- // panel3
- //
- this.panel3.Dock = System.Windows.Forms.DockStyle.Bottom;
- this.panel3.Location = new System.Drawing.Point(3, 422);
- this.panel3.Name = "panel3";
- this.panel3.Size = new System.Drawing.Size(390, 5);
- this.panel3.TabIndex = 4;
- //
// virtualFlowControl2
//
this.virtualFlowControl2.AccessibleRole = System.Windows.Forms.AccessibleRole.None;
@@ -174,14 +164,14 @@
this.panel1.Dock = System.Windows.Forms.DockStyle.Bottom;
this.panel1.Location = new System.Drawing.Point(3, 427);
this.panel1.Name = "panel1";
- this.panel1.Size = new System.Drawing.Size(390, 25);
+ this.panel1.Size = new System.Drawing.Size(390, 29);
this.panel1.TabIndex = 2;
//
// label1
//
this.label1.Anchor = System.Windows.Forms.AnchorStyles.Right;
this.label1.AutoSize = true;
- this.label1.Location = new System.Drawing.Point(148, 4);
+ this.label1.Location = new System.Drawing.Point(148, 6);
this.label1.Name = "label1";
this.label1.Size = new System.Drawing.Size(54, 15);
this.label1.TabIndex = 5;
@@ -196,7 +186,7 @@
0,
0,
65536});
- this.numericUpDown1.Location = new System.Drawing.Point(208, 0);
+ this.numericUpDown1.Location = new System.Drawing.Point(208, 2);
this.numericUpDown1.Maximum = new decimal(new int[] {
999,
0,
@@ -348,7 +338,6 @@
this.panel2.ResumeLayout(false);
this.ResumeLayout(false);
this.PerformLayout();
-
}
#endregion
@@ -367,7 +356,6 @@
private System.Windows.Forms.ToolStripStatusLabel queueNumberLbl;
private System.Windows.Forms.ToolStripStatusLabel completedNumberLbl;
private System.Windows.Forms.ToolStripStatusLabel errorNumberLbl;
- private System.Windows.Forms.Panel panel3;
private System.Windows.Forms.Panel panel4;
private System.Windows.Forms.ToolStripStatusLabel runningTimeLbl;
private System.Windows.Forms.DataGridView logDGV;
diff --git a/Source/LibationWinForms/ProcessQueue/ProcessQueueControl.cs b/Source/LibationWinForms/ProcessQueue/ProcessQueueControl.cs
index 76a7d43d..15bcc5d6 100644
--- a/Source/LibationWinForms/ProcessQueue/ProcessQueueControl.cs
+++ b/Source/LibationWinForms/ProcessQueue/ProcessQueueControl.cs
@@ -1,5 +1,4 @@
-using LibationFileManager;
-using LibationUiBase;
+using LibationUiBase;
using LibationUiBase.ProcessQueue;
using System;
using System.ComponentModel;
@@ -35,23 +34,18 @@ internal partial class ProcessQueueControl : UserControl
ViewModel.PropertyChanged += ProcessQueue_PropertyChanged;
ViewModel.LogEntries.CollectionChanged += LogEntries_CollectionChanged;
+ ProcessQueue_PropertyChanged(this, new PropertyChangedEventArgs(null));
}
private void LogEntries_CollectionChanged(object? sender, System.Collections.Specialized.NotifyCollectionChangedEventArgs e)
{
if (!IsDisposed && e.Action == System.Collections.Specialized.NotifyCollectionChangedAction.Add)
{
- foreach(var entry in e.NewItems?.OfType() ?? [])
+ foreach (var entry in e.NewItems?.OfType() ?? [])
logDGV.Rows.Add(entry.LogDate, entry.LogMessage);
}
}
- protected override void OnLoad(EventArgs e)
- {
- if (DesignMode) return;
- ProcessQueue_PropertyChanged(this, new PropertyChangedEventArgs(null));
- }
-
private async void cancelAllBtn_Click(object? sender, EventArgs e)
{
ViewModel.Queue.ClearQueue();
@@ -155,7 +149,7 @@ internal partial class ProcessQueueControl : UserControl
ViewModel.Queue.MoveQueuePosition(item, position.Value);
}
}
- catch(Exception ex)
+ catch (Exception ex)
{
Serilog.Log.Logger.Error(ex, "Error handling button click from queued item");
}