diff --git a/LibationWinForms/AsyncNotifyPropertyChanged.cs b/LibationWinForms/AsyncNotifyPropertyChanged.cs
index 20b8b512..96f007ed 100644
--- a/LibationWinForms/AsyncNotifyPropertyChanged.cs
+++ b/LibationWinForms/AsyncNotifyPropertyChanged.cs
@@ -1,6 +1,6 @@
-using System.ComponentModel;
+using Dinah.Core.Threading;
+using System.ComponentModel;
using System.Runtime.CompilerServices;
-using System.Threading;
namespace LibationWinForms
{
@@ -8,9 +8,7 @@ namespace LibationWinForms
{
public event PropertyChangedEventHandler PropertyChanged;
- public AsyncNotifyPropertyChanged() { }
-
protected void NotifyPropertyChanged([CallerMemberName] string propertyName = "")
- =>BeginInvoke(PropertyChanged, new object[] { this, new PropertyChangedEventArgs(propertyName) });
+ => this.UIThread(() => PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName)));
}
}
diff --git a/LibationWinForms/BookLiberation/BaseForms/LiberationBaseForm.cs b/LibationWinForms/BookLiberation/BaseForms/LiberationBaseForm.cs
index b69fa90d..dbf80104 100644
--- a/LibationWinForms/BookLiberation/BaseForms/LiberationBaseForm.cs
+++ b/LibationWinForms/BookLiberation/BaseForms/LiberationBaseForm.cs
@@ -1,6 +1,6 @@
using DataLayer;
using Dinah.Core.Net.Http;
-using Dinah.Core.Windows.Forms;
+using Dinah.Core.Threading;
using FileLiberator;
using System;
using System.Windows.Forms;
@@ -122,8 +122,8 @@ namespace LibationWinForms.BookLiberation.BaseForms
///
/// If the form was shown using Show (not ShowDialog), Form.Close calls Form.Dispose
///
- private void OnStreamingCompletedClose(object sender, string completedString) => this.UIThread(() => Close());
- private void OnCompletedDispose(object sender, LibraryBook e) => this.UIThread(() => Dispose());
+ private void OnStreamingCompletedClose(object sender, string completedString) => this.UIThread(Close);
+ private void OnCompletedDispose(object sender, LibraryBook e) => this.UIThread(Dispose);
///
/// If StreamingBegin is fired from a worker thread, the window will be created on that
@@ -132,7 +132,7 @@ namespace LibationWinForms.BookLiberation.BaseForms
/// could cause it to freeze. Form.BeginInvoke won't work until the form is created
/// (ie. shown) because Control doesn't get a window handle until it is Shown.
///
- private void OnStreamingBeginShow(object sender, string beginString) => Invoker.Invoke(Show);
+ private void OnStreamingBeginShow(object sender, string beginString) => Invoker.UIThread(Show);
#endregion
diff --git a/LibationWinForms/DataGridViewImageButtonCell.cs b/LibationWinForms/DataGridViewImageButtonCell.cs
new file mode 100644
index 00000000..f4f25afd
--- /dev/null
+++ b/LibationWinForms/DataGridViewImageButtonCell.cs
@@ -0,0 +1,18 @@
+using System.Drawing;
+using System.Windows.Forms;
+
+namespace LibationWinForms
+{
+ public class DataGridViewImageButtonCell : DataGridViewButtonCell
+ {
+ protected void DrawButtonImage(Graphics graphics, Image image, Rectangle cellBounds)
+ {
+ var w = image.Width;
+ var h = image.Height;
+ var x = cellBounds.Left + (cellBounds.Width - w) / 2;
+ var y = cellBounds.Top + (cellBounds.Height - h) / 2;
+
+ graphics.DrawImage(image, new Rectangle(x, y, w, h));
+ }
+ }
+}
diff --git a/LibationWinForms/DataGridViewImageButtonColumn.cs b/LibationWinForms/DataGridViewImageButtonColumn.cs
deleted file mode 100644
index e607a069..00000000
--- a/LibationWinForms/DataGridViewImageButtonColumn.cs
+++ /dev/null
@@ -1,50 +0,0 @@
-using System.Drawing;
-using System.Windows.Forms;
-
-namespace LibationWinForms
-{
- public abstract class DataGridViewImageButtonColumn : DataGridViewButtonColumn
- {
- private DataGridViewImageButtonCell _cellTemplate;
- public override DataGridViewCell CellTemplate
- {
- get => GetCellTemplate();
- set
- {
- if (value is DataGridViewImageButtonCell cellTemplate)
- _cellTemplate = cellTemplate;
- }
- }
-
- protected abstract DataGridViewImageButtonCell NewCell();
-
- private DataGridViewImageButtonCell GetCellTemplate()
- {
- if (_cellTemplate is null)
- return NewCell();
- else
- return _cellTemplate;
- }
-
- public override object Clone()
- {
- var clone = (DataGridViewImageButtonColumn)base.Clone();
- clone._cellTemplate = _cellTemplate;
-
- return clone;
- }
- }
-
- public class DataGridViewImageButtonCell : DataGridViewButtonCell
- {
- protected void DrawButtonImage(Graphics graphics, Image image, Rectangle cellBounds)
- {
- var w = image.Width;
- var h = image.Height;
- var x = cellBounds.Left + (cellBounds.Width - w) / 2;
- var y = cellBounds.Top + (cellBounds.Height - h) / 2;
-
- graphics.DrawImage(image, new Rectangle(x, y, w, h));
- }
- }
-}
diff --git a/LibationWinForms/EditTagsDataGridViewImageButtonColumn.cs b/LibationWinForms/EditTagsDataGridViewImageButtonColumn.cs
index e736b938..d76cc04a 100644
--- a/LibationWinForms/EditTagsDataGridViewImageButtonColumn.cs
+++ b/LibationWinForms/EditTagsDataGridViewImageButtonColumn.cs
@@ -3,10 +3,12 @@ using System.Windows.Forms;
namespace LibationWinForms
{
- public class EditTagsDataGridViewImageButtonColumn : DataGridViewImageButtonColumn
+ public class EditTagsDataGridViewImageButtonColumn : DataGridViewButtonColumn
{
- protected override DataGridViewImageButtonCell NewCell()
- => new EditTagsDataGridViewImageButtonCell();
+ public EditTagsDataGridViewImageButtonColumn()
+ {
+ CellTemplate = new EditTagsDataGridViewImageButtonCell();
+ }
}
internal class EditTagsDataGridViewImageButtonCell : DataGridViewImageButtonCell
diff --git a/LibationWinForms/GridEntry.cs b/LibationWinForms/GridEntry.cs
index d66b8a73..857469c6 100644
--- a/LibationWinForms/GridEntry.cs
+++ b/LibationWinForms/GridEntry.cs
@@ -7,6 +7,7 @@ using System.Linq;
using ApplicationServices;
using DataLayer;
using Dinah.Core.DataBinding;
+using Dinah.Core;
using Dinah.Core.Drawing;
namespace LibationWinForms
@@ -47,9 +48,9 @@ namespace LibationWinForms
Title = Book.Title;
Series = Book.SeriesNames;
Length = Book.LengthInMinutes == 0 ? "" : $"{Book.LengthInMinutes / 60} hr {Book.LengthInMinutes % 60} min";
- MyRating = ValueOrDefault(Book.UserDefinedItem.Rating?.ToStarString(), "");
+ MyRating = Book.UserDefinedItem.Rating?.ToStarString()?.DefaultIfNullOrWhiteSpace("");
PurchaseDate = libraryBook.DateAdded.ToString("d");
- ProductRating = ValueOrDefault(Book.Rating?.ToStarString(), "");
+ ProductRating = Book.Rating?.ToStarString()?.DefaultIfNullOrWhiteSpace("");
Authors = Book.AuthorNames;
Narrators = Book.NarratorNames;
Category = string.Join(" > ", Book.CategoriesNames);
@@ -207,8 +208,8 @@ namespace LibationWinForms
{
var details = new List();
- var locale = ValueOrDefault(libraryBook.Book.Locale, "[unknown]");
- var acct = ValueOrDefault(libraryBook.Account, "[unknown]");
+ var locale = libraryBook.Book.Locale.DefaultIfNullOrWhiteSpace("[unknown]");
+ var acct = libraryBook.Account.DefaultIfNullOrWhiteSpace("[unknown]");
details.Add($"Account: {locale} - {acct}");
@@ -228,10 +229,6 @@ namespace LibationWinForms
return string.Join("\r\n", details);
}
- //Maybe add to Dinah StringExtensions?
- private static string ValueOrDefault(string value, string defaultValue)
- => string.IsNullOrWhiteSpace(value) ? defaultValue : value;
-
#endregion
}
}
diff --git a/LibationWinForms/LiberateDataGridViewImageButtonColumn.cs b/LibationWinForms/LiberateDataGridViewImageButtonColumn.cs
index 4802fa96..6427677c 100644
--- a/LibationWinForms/LiberateDataGridViewImageButtonColumn.cs
+++ b/LibationWinForms/LiberateDataGridViewImageButtonColumn.cs
@@ -6,10 +6,12 @@ using System.Linq;
namespace LibationWinForms
{
- public class LiberateDataGridViewImageButtonColumn : DataGridViewImageButtonColumn
+ public class LiberateDataGridViewImageButtonColumn : DataGridViewButtonColumn
{
- protected override DataGridViewImageButtonCell NewCell()
- => new LiberateDataGridViewImageButtonCell();
+ public LiberateDataGridViewImageButtonColumn()
+ {
+ CellTemplate = new LiberateDataGridViewImageButtonCell();
+ }
}
internal class LiberateDataGridViewImageButtonCell : DataGridViewImageButtonCell
diff --git a/LibationWinForms/ProductsGrid.Designer.cs b/LibationWinForms/ProductsGrid.Designer.cs
index 529a7783..82f5703e 100644
--- a/LibationWinForms/ProductsGrid.Designer.cs
+++ b/LibationWinForms/ProductsGrid.Designer.cs
@@ -92,7 +92,7 @@
this.gridEntryDataGridView.ReadOnly = true;
this.gridEntryDataGridView.RowHeadersVisible = false;
this.gridEntryDataGridView.RowTemplate.Height = 82;
- this.gridEntryDataGridView.Size = new System.Drawing.Size(1505, 380);
+ this.gridEntryDataGridView.Size = new System.Drawing.Size(1510, 380);
this.gridEntryDataGridView.TabIndex = 0;
//
// dataGridViewImageButtonBoxColumn1
@@ -103,7 +103,7 @@
this.dataGridViewImageButtonBoxColumn1.ReadOnly = true;
this.dataGridViewImageButtonBoxColumn1.Resizable = System.Windows.Forms.DataGridViewTriState.False;
this.dataGridViewImageButtonBoxColumn1.SortMode = System.Windows.Forms.DataGridViewColumnSortMode.Automatic;
- this.dataGridViewImageButtonBoxColumn1.Width = 70;
+ this.dataGridViewImageButtonBoxColumn1.Width = 75;
//
// dataGridViewImageColumn1
//
@@ -213,7 +213,7 @@
this.Controls.Add(this.gridEntryDataGridView);
this.Margin = new System.Windows.Forms.Padding(4, 3, 4, 3);
this.Name = "ProductsGrid";
- this.Size = new System.Drawing.Size(1505, 380);
+ this.Size = new System.Drawing.Size(1510, 380);
((System.ComponentModel.ISupportInitialize)(this.gridEntryBindingSource)).EndInit();
((System.ComponentModel.ISupportInitialize)(this.gridEntryDataGridView)).EndInit();
this.ResumeLayout(false);
diff --git a/LibationWinForms/SynchronizeInvoker.cs b/LibationWinForms/SynchronizeInvoker.cs
deleted file mode 100644
index c38c0499..00000000
--- a/LibationWinForms/SynchronizeInvoker.cs
+++ /dev/null
@@ -1,122 +0,0 @@
-using System;
-using System.ComponentModel;
-using System.Threading;
-
-namespace LibationWinForms
-{
- public class SynchronizeInvoker : ISynchronizeInvoke
- {
- public bool InvokeRequired => Thread.CurrentThread.ManagedThreadId != InstanceThreadId;
- private int InstanceThreadId { get; set; } = Thread.CurrentThread.ManagedThreadId;
- private SynchronizationContext SyncContext { get; } = SynchronizationContext.Current;
-
- public SynchronizeInvoker()
- {
- if (SyncContext is null)
- throw new NullReferenceException($"Could not capture a current {nameof(SynchronizationContext)}");
- }
-
- public IAsyncResult BeginInvoke(Action action) => BeginInvoke(action, null);
- public IAsyncResult BeginInvoke(Delegate method) => BeginInvoke(method, null);
- public IAsyncResult BeginInvoke(Delegate method, object[] args)
- {
- var tme = new ThreadMethodEntry(method, args);
-
- if (InvokeRequired)
- {
- SyncContext.Post(OnSendOrPostCallback, tme);
- }
- else
- {
- tme.Complete();
- tme.CompletedSynchronously = true;
- }
- return tme;
- }
-
- public object EndInvoke(IAsyncResult result)
- {
- if (result is not ThreadMethodEntry crossThread)
- throw new ArgumentException($"{nameof(result)} was not returned by {nameof(SynchronizeInvoker)}.{nameof(BeginInvoke)}");
-
- if (!crossThread.IsCompleted)
- crossThread.AsyncWaitHandle.WaitOne();
-
- return crossThread.ReturnValue;
- }
-
- public object Invoke(Action action) => Invoke(action, null);
- public object Invoke(Delegate method) => Invoke(method, null);
- public object Invoke(Delegate method, object[] args)
- {
- var tme = new ThreadMethodEntry(method, args);
-
- if (InvokeRequired)
- {
- SyncContext.Send(OnSendOrPostCallback, tme);
- }
- else
- {
- tme.Complete();
- tme.CompletedSynchronously = true;
- }
-
- return tme.ReturnValue;
- }
-
- ///
- /// This callback executes on the SynchronizationContext thread.
- ///
- private static void OnSendOrPostCallback(object asyncArgs)
- {
- var e = asyncArgs as ThreadMethodEntry;
- e.Complete();
- }
-
- private class ThreadMethodEntry : IAsyncResult
- {
- public object AsyncState => null;
- public bool CompletedSynchronously { get; internal set; }
- public bool IsCompleted { get; private set; }
- public object ReturnValue { get; private set; }
- public WaitHandle AsyncWaitHandle => completedEvent;
-
- private Delegate method;
- private object[] args;
- private ManualResetEvent completedEvent;
-
- public ThreadMethodEntry(Delegate method, object[] args)
- {
- this.method = method;
- this.args = args;
- completedEvent = new ManualResetEvent(initialState: false);
- }
-
- public void Complete()
- {
- try
- {
- switch (method)
- {
- case Action actiton:
- actiton();
- break;
- default:
- ReturnValue = method.DynamicInvoke(args);
- break;
- }
- }
- finally
- {
- IsCompleted = true;
- completedEvent.Set();
- }
- }
-
- ~ThreadMethodEntry()
- {
- completedEvent.Close();
- }
- }
- }
-}
\ No newline at end of file