Finish MVVM conversion
This commit is contained in:
parent
9e06c343c1
commit
2a7e185dc3
@ -163,6 +163,7 @@ namespace ApplicationServices
|
|||||||
using var context = DbContexts.GetContext();
|
using var context = DbContexts.GetContext();
|
||||||
|
|
||||||
var udi = libraryBook.UserDefinedItem;
|
var udi = libraryBook.UserDefinedItem;
|
||||||
|
udi.Tags = newTags;
|
||||||
|
|
||||||
// Attach() NoTracking entities before SaveChanges()
|
// Attach() NoTracking entities before SaveChanges()
|
||||||
context.Attach(udi).State = Microsoft.EntityFrameworkCore.EntityState.Modified;
|
context.Attach(udi).State = Microsoft.EntityFrameworkCore.EntityState.Modified;
|
||||||
@ -186,6 +187,7 @@ namespace ApplicationServices
|
|||||||
using var context = DbContexts.GetContext();
|
using var context = DbContexts.GetContext();
|
||||||
|
|
||||||
var udi = libraryBook.UserDefinedItem;
|
var udi = libraryBook.UserDefinedItem;
|
||||||
|
udi.BookStatus = liberatedStatus;
|
||||||
|
|
||||||
// Attach() NoTracking entities before SaveChanges()
|
// Attach() NoTracking entities before SaveChanges()
|
||||||
context.Attach(udi).State = Microsoft.EntityFrameworkCore.EntityState.Modified;
|
context.Attach(udi).State = Microsoft.EntityFrameworkCore.EntityState.Modified;
|
||||||
@ -209,6 +211,7 @@ namespace ApplicationServices
|
|||||||
using var context = DbContexts.GetContext();
|
using var context = DbContexts.GetContext();
|
||||||
|
|
||||||
var udi = libraryBook.UserDefinedItem;
|
var udi = libraryBook.UserDefinedItem;
|
||||||
|
udi.PdfStatus = liberatedStatus;
|
||||||
|
|
||||||
// Attach() NoTracking entities before SaveChanges()
|
// Attach() NoTracking entities before SaveChanges()
|
||||||
context.Attach(udi).State = Microsoft.EntityFrameworkCore.EntityState.Modified;
|
context.Attach(udi).State = Microsoft.EntityFrameworkCore.EntityState.Modified;
|
||||||
|
|||||||
@ -44,9 +44,13 @@ namespace DataLayer
|
|||||||
get => _tags;
|
get => _tags;
|
||||||
set
|
set
|
||||||
{
|
{
|
||||||
_tags = sanitize(value);
|
var newTags = sanitize(value);
|
||||||
|
if (_tags != newTags)
|
||||||
|
{
|
||||||
|
_tags = newTags;
|
||||||
ItemChanged?.Invoke(this, nameof(Tags));
|
ItemChanged?.Invoke(this, nameof(Tags));
|
||||||
}
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public IEnumerable<string> TagsEnumerated => Tags == "" ? new string[0] : Tags.Split(null as char[], StringSplitOptions.RemoveEmptyEntries);
|
public IEnumerable<string> TagsEnumerated => Tags == "" ? new string[0] : Tags.Split(null as char[], StringSplitOptions.RemoveEmptyEntries);
|
||||||
|
|||||||
@ -384,15 +384,14 @@ namespace LibationWinForms
|
|||||||
|
|
||||||
#region liberate menu
|
#region liberate menu
|
||||||
private async void beginBookBackupsToolStripMenuItem_Click(object sender, EventArgs e)
|
private async void beginBookBackupsToolStripMenuItem_Click(object sender, EventArgs e)
|
||||||
=> await BookLiberation.ProcessorAutomationController.BackupAllBooksAsync(updateGridRow);
|
=> await BookLiberation.ProcessorAutomationController.BackupAllBooksAsync();
|
||||||
|
|
||||||
private async void beginPdfBackupsToolStripMenuItem_Click(object sender, EventArgs e)
|
private async void beginPdfBackupsToolStripMenuItem_Click(object sender, EventArgs e)
|
||||||
=> await BookLiberation.ProcessorAutomationController.BackupAllPdfsAsync(updateGridRow);
|
=> await BookLiberation.ProcessorAutomationController.BackupAllPdfsAsync();
|
||||||
|
|
||||||
private async void convertAllM4bToMp3ToolStripMenuItem_Click(object sender, EventArgs e)
|
private async void convertAllM4bToMp3ToolStripMenuItem_Click(object sender, EventArgs e)
|
||||||
=> await BookLiberation.ProcessorAutomationController.ConvertAllBooksAsync();
|
=> await BookLiberation.ProcessorAutomationController.ConvertAllBooksAsync();
|
||||||
|
|
||||||
private void updateGridRow(object _, LibraryBook libraryBook) => currProductsGrid.RefreshLiberatedStatus(libraryBook);
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
#region Export menu
|
#region Export menu
|
||||||
|
|||||||
@ -12,6 +12,9 @@ using Dinah.Core.Drawing;
|
|||||||
|
|
||||||
namespace LibationWinForms
|
namespace LibationWinForms
|
||||||
{
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// The View Model for a LibraryBook
|
||||||
|
/// </summary>
|
||||||
internal class GridEntry : AsyncNotifyPropertyChanged, IMemberComparable
|
internal class GridEntry : AsyncNotifyPropertyChanged, IMemberComparable
|
||||||
{
|
{
|
||||||
#region implementation properties
|
#region implementation properties
|
||||||
@ -26,12 +29,15 @@ namespace LibationWinForms
|
|||||||
|
|
||||||
private Book Book => LibraryBook.Book;
|
private Book Book => LibraryBook.Book;
|
||||||
private Image _cover;
|
private Image _cover;
|
||||||
|
private Action _refilter;
|
||||||
|
|
||||||
public GridEntry(LibraryBook libraryBook)
|
public GridEntry(LibraryBook libraryBook, Action refilterOnChanged = null)
|
||||||
{
|
{
|
||||||
LibraryBook = libraryBook;
|
LibraryBook = libraryBook;
|
||||||
|
_refilter = refilterOnChanged;
|
||||||
_memberValues = CreateMemberValueDictionary();
|
_memberValues = CreateMemberValueDictionary();
|
||||||
|
|
||||||
|
|
||||||
//Get cover art. If it's default, subscribe to PictureCached
|
//Get cover art. If it's default, subscribe to PictureCached
|
||||||
{
|
{
|
||||||
(bool isDefault, byte[] picture) = FileManager.PictureStorage.GetPicture(new FileManager.PictureDefinition(Book.PictureId, FileManager.PictureSize._80x80));
|
(bool isDefault, byte[] picture) = FileManager.PictureStorage.GetPicture(new FileManager.PictureDefinition(Book.PictureId, FileManager.PictureSize._80x80));
|
||||||
@ -58,7 +64,7 @@ namespace LibationWinForms
|
|||||||
Description = GetDescriptionDisplay(Book);
|
Description = GetDescriptionDisplay(Book);
|
||||||
}
|
}
|
||||||
|
|
||||||
//DisplayTags and Liberate properties are live.
|
UserDefinedItem.ItemChanged += UserDefinedItem_ItemChanged;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void PictureStorage_PictureCached(object sender, FileManager.PictureCachedEventArgs e)
|
private void PictureStorage_PictureCached(object sender, FileManager.PictureCachedEventArgs e)
|
||||||
@ -70,7 +76,48 @@ namespace LibationWinForms
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#region Data Source properties
|
#region detect changes to the model and update the view
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// This event handler receives notifications from the model that it has changed.
|
||||||
|
/// Save to the database and notify the view that it's changed.
|
||||||
|
/// </summary>
|
||||||
|
private void UserDefinedItem_ItemChanged(object sender, string itemName)
|
||||||
|
{
|
||||||
|
var udi = sender as UserDefinedItem;
|
||||||
|
|
||||||
|
if (udi.Book.AudibleProductId != LibraryBook.Book.AudibleProductId)
|
||||||
|
return;
|
||||||
|
|
||||||
|
switch (itemName)
|
||||||
|
{
|
||||||
|
case nameof(udi.Tags):
|
||||||
|
{
|
||||||
|
LibraryCommands.UpdateTags(LibraryBook.Book, udi.Tags);
|
||||||
|
NotifyPropertyChanged(nameof(DisplayTags));
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case nameof(udi.BookStatus):
|
||||||
|
{
|
||||||
|
var status = udi.BookStatus == LiberatedStatus.PartialDownload ? LiberatedStatus.NotLiberated : udi.BookStatus;
|
||||||
|
LibraryCommands.UpdateBook(LibraryBook.Book, status);
|
||||||
|
NotifyPropertyChanged(nameof(Liberate));
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case nameof(udi.PdfStatus):
|
||||||
|
{
|
||||||
|
LibraryCommands.UpdatePdf(LibraryBook.Book, udi.PdfStatus);
|
||||||
|
NotifyPropertyChanged(nameof(Liberate));
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
_refilter?.Invoke();
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region Model properties exposed to the view
|
||||||
public Image Cover
|
public Image Cover
|
||||||
{
|
{
|
||||||
get
|
get
|
||||||
@ -95,8 +142,22 @@ namespace LibationWinForms
|
|||||||
public string Category { get; }
|
public string Category { get; }
|
||||||
public string Misc { get; }
|
public string Misc { get; }
|
||||||
public string Description { get; }
|
public string Description { get; }
|
||||||
public string DisplayTags => string.Join("\r\n", Book.UserDefinedItem.TagsEnumerated);
|
public string DisplayTags
|
||||||
public (LiberatedStatus BookStatus, LiberatedStatus? PdfStatus) Liberate => (LibraryCommands.Liberated_Status(Book), LibraryCommands.Pdf_Status(Book));
|
{
|
||||||
|
get=> Book.UserDefinedItem.Tags;
|
||||||
|
set => Book.UserDefinedItem.Tags = value;
|
||||||
|
}
|
||||||
|
public (LiberatedStatus BookStatus, LiberatedStatus? PdfStatus) Liberate
|
||||||
|
{
|
||||||
|
get => (LibraryCommands.Liberated_Status(LibraryBook.Book), LibraryCommands.Pdf_Status(LibraryBook.Book));
|
||||||
|
|
||||||
|
set
|
||||||
|
{
|
||||||
|
LibraryBook.Book.UserDefinedItem.BookStatus = value.BookStatus;
|
||||||
|
LibraryBook.Book.UserDefinedItem.PdfStatus = value.PdfStatus;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
#region Data Sorting
|
#region Data Sorting
|
||||||
@ -199,5 +260,12 @@ namespace LibationWinForms
|
|||||||
}
|
}
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
|
~GridEntry()
|
||||||
|
{
|
||||||
|
UserDefinedItem.ItemChanged -= UserDefinedItem_ItemChanged;
|
||||||
|
FileManager.PictureStorage.PictureCached -= PictureStorage_PictureCached;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|||||||
@ -86,7 +86,7 @@ namespace LibationWinForms
|
|||||||
}
|
}
|
||||||
|
|
||||||
// else: liberate
|
// else: liberate
|
||||||
await BookLiberation.ProcessorAutomationController.BackupSingleBookAsync(libraryBook, (_, __) => RefreshRow(libraryBook.Book.AudibleProductId));
|
await BookLiberation.ProcessorAutomationController.BackupSingleBookAsync(libraryBook);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void Details_Click(GridEntry liveGridEntry)
|
private void Details_Click(GridEntry liveGridEntry)
|
||||||
@ -95,15 +95,10 @@ namespace LibationWinForms
|
|||||||
if (bookDetailsForm.ShowDialog() != DialogResult.OK)
|
if (bookDetailsForm.ShowDialog() != DialogResult.OK)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
var qtyChanges = LibraryCommands.UpdateUserDefinedItem(liveGridEntry.LibraryBook.Book, bookDetailsForm.NewTags, bookDetailsForm.BookLiberatedStatus, bookDetailsForm.PdfLiberatedStatus);
|
liveGridEntry.DisplayTags = bookDetailsForm.NewTags;
|
||||||
if (qtyChanges == 0)
|
liveGridEntry.Liberate = (bookDetailsForm.BookLiberatedStatus, bookDetailsForm.PdfLiberatedStatus);
|
||||||
return;
|
|
||||||
|
|
||||||
//Re-apply filters
|
BackupCountsChanged?.Invoke(this, EventArgs.Empty);
|
||||||
Filter();
|
|
||||||
|
|
||||||
//Update whole GridEntry row
|
|
||||||
liveGridEntry.NotifyPropertyChanged();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
@ -132,7 +127,7 @@ namespace LibationWinForms
|
|||||||
}
|
}
|
||||||
|
|
||||||
var orderedGridEntries = lib
|
var orderedGridEntries = lib
|
||||||
.Select(lb => new GridEntry(lb)).ToList()
|
.Select(lb => new GridEntry(lb, Filter)).ToList()
|
||||||
// default load order
|
// default load order
|
||||||
.OrderByDescending(ge => (DateTime)ge.GetMemberValue(nameof(ge.PurchaseDate)))
|
.OrderByDescending(ge => (DateTime)ge.GetMemberValue(nameof(ge.PurchaseDate)))
|
||||||
//// more advanced example: sort by author, then series, then title
|
//// more advanced example: sort by author, then series, then title
|
||||||
@ -150,19 +145,6 @@ namespace LibationWinForms
|
|||||||
BackupCountsChanged?.Invoke(this, EventArgs.Empty);
|
BackupCountsChanged?.Invoke(this, EventArgs.Empty);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void RefreshRow(string productId)
|
|
||||||
{
|
|
||||||
var liveGridEntry = getGridEntry((ge) => ge.AudibleProductId == productId);
|
|
||||||
|
|
||||||
// update GridEntry Liberate cell
|
|
||||||
liveGridEntry?.NotifyPropertyChanged(nameof(liveGridEntry.Liberate));
|
|
||||||
|
|
||||||
// needed in case filtering by -IsLiberated and it gets changed to Liberated. want to immediately show the change
|
|
||||||
Filter();
|
|
||||||
|
|
||||||
BackupCountsChanged?.Invoke(this, EventArgs.Empty);
|
|
||||||
}
|
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
#region Filter
|
#region Filter
|
||||||
@ -195,12 +177,7 @@ namespace LibationWinForms
|
|||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
#region DataGridView Macro
|
#region DataGridView Macro
|
||||||
|
|
||||||
private GridEntry getGridEntry(Func<GridEntry, bool> predicate)
|
|
||||||
=> ((SortableBindingList<GridEntry>)gridEntryBindingSource.DataSource).FirstOrDefault(predicate);
|
|
||||||
|
|
||||||
private GridEntry getGridEntry(int rowIndex) => _dataGridView.GetBoundItem<GridEntry>(rowIndex);
|
private GridEntry getGridEntry(int rowIndex) => _dataGridView.GetBoundItem<GridEntry>(rowIndex);
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user