diff --git a/Source/LibationWinForms/AvaloniaUI/ViewModels/MainWindowViewModel.cs b/Source/LibationWinForms/AvaloniaUI/ViewModels/MainWindowViewModel.cs
index b4bfe0b9..9e688a2f 100644
--- a/Source/LibationWinForms/AvaloniaUI/ViewModels/MainWindowViewModel.cs
+++ b/Source/LibationWinForms/AvaloniaUI/ViewModels/MainWindowViewModel.cs
@@ -21,7 +21,7 @@ namespace LibationWinForms.AvaloniaUI.ViewModels
private int _visibleNotLiberated = 1;
/// The Process Queue's viewmodel
- public ProcessQueueViewModel ProcessQueueViewModel { get; } = new ProcessQueueViewModel();
+ public ProcessQueueViewModel ProcessQueue { get; } = new ProcessQueueViewModel();
public ProductsDisplayViewModel ProductsDisplay { get; } = new ProductsDisplayViewModel();
diff --git a/Source/LibationWinForms/AvaloniaUI/ViewModels/ProductsDisplayViewModel.cs b/Source/LibationWinForms/AvaloniaUI/ViewModels/ProductsDisplayViewModel.cs
index f3859d95..15da47cf 100644
--- a/Source/LibationWinForms/AvaloniaUI/ViewModels/ProductsDisplayViewModel.cs
+++ b/Source/LibationWinForms/AvaloniaUI/ViewModels/ProductsDisplayViewModel.cs
@@ -1,12 +1,9 @@
-using Avalonia.Collections;
using Avalonia.Controls;
using DataLayer;
using System;
using System.Collections.Generic;
using System.ComponentModel;
-using System.Globalization;
using System.Linq;
-using System.Text;
using System.Threading.Tasks;
using ReactiveUI;
using System.Reflection;
@@ -14,25 +11,25 @@ using System.Collections;
using Avalonia.Threading;
using ApplicationServices;
using AudibleUtilities;
+using LibationWinForms.AvaloniaUI.Views;
namespace LibationWinForms.AvaloniaUI.ViewModels
{
public class ProductsDisplayViewModel : ViewModelBase
{
-
/// Number of visible rows has changed
public event EventHandler VisibleCountChanged;
public event EventHandler RemovableCountChanged;
public event EventHandler InitialLoaded;
private DataGridColumn _currentSortColumn;
+ private DataGrid productsDataGrid;
private GridEntryBindingList2 _gridEntries;
private bool _removeColumnVisivle;
public GridEntryBindingList2 GridEntries { get => _gridEntries; private set => this.RaiseAndSetIfChanged(ref _gridEntries, value); }
public bool RemoveColumnVisivle { get => _removeColumnVisivle; private set => this.RaiseAndSetIfChanged(ref _removeColumnVisivle, value); }
-
public List GetVisibleBookEntries()
=> GridEntries
.BookEntries()
@@ -49,14 +46,47 @@ namespace LibationWinForms.AvaloniaUI.ViewModels
{
using var context = DbContexts.GetContext();
var book = context.GetLibraryBook_Flat_NoTracking("B017V4IM1G");
- _gridEntries = new GridEntryBindingList2(CreateGridEntries(new List { book }));
+ GridEntries = new GridEntryBindingList2(CreateGridEntries(new List { book }));
return;
}
}
- public void InitialDisplay(List dbBooks, Views.ProductsDisplay2 productsGrid)
- {
+ #region Display Functions
+ ///
+ /// Call once on load so we can modify access a private member with reflection
+ ///
+ public void RegisterCollectionChanged(ProductsDisplay2 productsDisplay = null)
+ {
+ productsDataGrid ??= productsDisplay?.productsGrid;
+
+ if (GridEntries is null)
+ return;
+
+ //Avalonia displays items in the DataConncetion from an internal copy of
+ //the bound list, not the actual bound list. So we need to reflect to get
+ //the current display order and set each GridEntry.ListIndex correctly.
+ var DataConnection_PI = typeof(DataGrid).GetProperty("DataConnection", BindingFlags.NonPublic | BindingFlags.Instance);
+ var DataSource_PI = DataConnection_PI.PropertyType.GetProperty("DataSource", BindingFlags.Public | BindingFlags.Instance);
+
+ GridEntries.CollectionChanged += (s, e) =>
+ {
+ if (s != GridEntries) return;
+
+ var displayListGE = ((IEnumerable)DataSource_PI.GetValue(DataConnection_PI.GetValue(productsDataGrid))).Cast();
+ int index = 0;
+ foreach (var di in displayListGE)
+ {
+ di.ListIndex = index++;
+ }
+ };
+ }
+
+ ///
+ /// Only call once per lifetime
+ ///
+ public void InitialDisplay(List dbBooks)
+ {
try
{
GridEntries = new GridEntryBindingList2(CreateGridEntries(dbBooks));
@@ -67,21 +97,7 @@ namespace LibationWinForms.AvaloniaUI.ViewModels
InitialLoaded?.Invoke(this, EventArgs.Empty);
VisibleCountChanged?.Invoke(this, bookEntryCount);
- //Avalonia displays items in the DataConncetion from an internal copy of
- //the bound list, not the actual bound list. So we need to reflect to get
- //the current display order and set each GridEntry.ListIndex correctly.
- var DataConnection_PI = typeof(DataGrid).GetProperty("DataConnection", BindingFlags.NonPublic | BindingFlags.Instance);
- var DataSource_PI = DataConnection_PI.PropertyType.GetProperty("DataSource", BindingFlags.Public | BindingFlags.Instance);
-
- GridEntries.CollectionChanged += (s, e) =>
- {
- var displayListGE = ((IEnumerable)DataSource_PI.GetValue(DataConnection_PI.GetValue(productsGrid.productsGrid))).Cast();
- int index = 0;
- foreach (var di in displayListGE)
- {
- di.ListIndex = index++;
- }
- };
+ RegisterCollectionChanged();
}
catch (Exception ex)
{
@@ -89,9 +105,11 @@ namespace LibationWinForms.AvaloniaUI.ViewModels
}
}
+ ///
+ /// Call when there's been a change to the library
+ ///
public async Task DisplayBooks(List dbBooks)
{
-
try
{
//List is already displayed. Replace all items with new ones, refilter, and re-sort
@@ -148,7 +166,19 @@ namespace LibationWinForms.AvaloniaUI.ViewModels
return geList.OrderByDescending(e => e.DateAdded);
}
+ public void ToggleSeriesExpanded(SeriesEntrys2 seriesEntry)
+ {
+ if (seriesEntry.Liberate.Expanded)
+ GridEntries.CollapseItem(seriesEntry);
+ else
+ GridEntries.ExpandItem(seriesEntry);
+ VisibleCountChanged?.Invoke(this, GridEntries.BookEntries().Count());
+ }
+
+ #endregion
+
+ #region Filtering
public async Task Filter(string searchString)
{
await Dispatcher.UIThread.InvokeAsync(() =>
@@ -168,16 +198,9 @@ namespace LibationWinForms.AvaloniaUI.ViewModels
});
}
- public void ToggleSeriesExpanded(SeriesEntrys2 seriesEntry)
- {
- if (seriesEntry.Liberate.Expanded)
- GridEntries.CollapseItem(seriesEntry);
- else
- GridEntries.ExpandItem(seriesEntry);
-
- VisibleCountChanged?.Invoke(this, GridEntries.BookEntries().Count());
- }
+ #endregion
+ #region Sorting
public void Sort(DataGridColumn sortColumn)
{
@@ -207,6 +230,10 @@ namespace LibationWinForms.AvaloniaUI.ViewModels
}
}
+ #endregion
+
+ #region Scan and Remove Books
+
public void DoneRemovingBooks()
{
foreach (var item in GridEntries.AllItems())
@@ -311,5 +338,7 @@ namespace LibationWinForms.AvaloniaUI.ViewModels
RemovableCountChanged?.Invoke(this, removeCount);
}
}
+
+ #endregion
}
}
diff --git a/Source/LibationWinForms/AvaloniaUI/Views/MainWindow/MainWindow.Liberate.axaml.cs b/Source/LibationWinForms/AvaloniaUI/Views/MainWindow/MainWindow.Liberate.axaml.cs
index c19ac0ce..d021f762 100644
--- a/Source/LibationWinForms/AvaloniaUI/Views/MainWindow/MainWindow.Liberate.axaml.cs
+++ b/Source/LibationWinForms/AvaloniaUI/Views/MainWindow/MainWindow.Liberate.axaml.cs
@@ -19,7 +19,7 @@ namespace LibationWinForms.AvaloniaUI.Views
Serilog.Log.Logger.Information("Begin backing up all library books");
- _viewModel.ProcessQueueViewModel.AddDownloadDecrypt(
+ _viewModel.ProcessQueue.AddDownloadDecrypt(
ApplicationServices.DbContexts
.GetLibrary_Flat_NoTracking()
.UnLiberated()
@@ -34,7 +34,7 @@ namespace LibationWinForms.AvaloniaUI.Views
public async void beginPdfBackupsToolStripMenuItem_Click(object sender, Avalonia.Interactivity.RoutedEventArgs args)
{
SetQueueCollapseState(false);
- await Task.Run(() => _viewModel.ProcessQueueViewModel.AddDownloadPdf(ApplicationServices.DbContexts.GetLibrary_Flat_NoTracking()
+ await Task.Run(() => _viewModel.ProcessQueue.AddDownloadPdf(ApplicationServices.DbContexts.GetLibrary_Flat_NoTracking()
.Where(lb => lb.Book.UserDefinedItem.PdfStatus is DataLayer.LiberatedStatus.NotLiberated)));
}
@@ -51,7 +51,7 @@ namespace LibationWinForms.AvaloniaUI.Views
if (result == DialogResult.Yes)
{
SetQueueCollapseState(false);
- await Task.Run(() => _viewModel.ProcessQueueViewModel.AddConvertMp3(ApplicationServices.DbContexts.GetLibrary_Flat_NoTracking()
+ await Task.Run(() => _viewModel.ProcessQueue.AddConvertMp3(ApplicationServices.DbContexts.GetLibrary_Flat_NoTracking()
.Where(lb => lb.Book.UserDefinedItem.BookStatus is DataLayer.LiberatedStatus.Liberated && lb.Book.ContentType is DataLayer.ContentType.Product)));
}
//Only Queue Liberated books for conversion. This isn't a perfect filter, but it's better than nothing.
diff --git a/Source/LibationWinForms/AvaloniaUI/Views/MainWindow/MainWindow.ProcessQueue.axaml.cs b/Source/LibationWinForms/AvaloniaUI/Views/MainWindow/MainWindow.ProcessQueue.axaml.cs
index 05d80140..c334dbff 100644
--- a/Source/LibationWinForms/AvaloniaUI/Views/MainWindow/MainWindow.ProcessQueue.axaml.cs
+++ b/Source/LibationWinForms/AvaloniaUI/Views/MainWindow/MainWindow.ProcessQueue.axaml.cs
@@ -23,13 +23,13 @@ namespace LibationWinForms.AvaloniaUI.Views
{
Serilog.Log.Logger.Information("Begin single book backup of {libraryBook}", libraryBook);
SetQueueCollapseState(false);
- _viewModel.ProcessQueueViewModel.AddDownloadDecrypt(libraryBook);
+ _viewModel.ProcessQueue.AddDownloadDecrypt(libraryBook);
}
else if (libraryBook.Book.UserDefinedItem.PdfStatus is LiberatedStatus.NotLiberated)
{
Serilog.Log.Logger.Information("Begin single pdf backup of {libraryBook}", libraryBook);
SetQueueCollapseState(false);
- _viewModel.ProcessQueueViewModel.AddDownloadPdf(libraryBook);
+ _viewModel.ProcessQueue.AddDownloadPdf(libraryBook);
}
else if (libraryBook.Book.Audio_Exists())
{
diff --git a/Source/LibationWinForms/AvaloniaUI/Views/MainWindow/MainWindow.VisibleBooks.axaml.cs b/Source/LibationWinForms/AvaloniaUI/Views/MainWindow/MainWindow.VisibleBooks.axaml.cs
index 7241b0de..cafcbc39 100644
--- a/Source/LibationWinForms/AvaloniaUI/Views/MainWindow/MainWindow.VisibleBooks.axaml.cs
+++ b/Source/LibationWinForms/AvaloniaUI/Views/MainWindow/MainWindow.VisibleBooks.axaml.cs
@@ -27,7 +27,7 @@ namespace LibationWinForms.AvaloniaUI.Views
Serilog.Log.Logger.Information("Begin backing up visible library books");
- _viewModel.ProcessQueueViewModel.AddDownloadDecrypt(
+ _viewModel.ProcessQueue.AddDownloadDecrypt(
_viewModel
.ProductsDisplay
.GetVisibleBookEntries()
diff --git a/Source/LibationWinForms/AvaloniaUI/Views/MainWindow/MainWindow.axaml b/Source/LibationWinForms/AvaloniaUI/Views/MainWindow/MainWindow.axaml
index d42d0342..0693b3b7 100644
--- a/Source/LibationWinForms/AvaloniaUI/Views/MainWindow/MainWindow.axaml
+++ b/Source/LibationWinForms/AvaloniaUI/Views/MainWindow/MainWindow.axaml
@@ -167,14 +167,14 @@
-
+
+ LiberateClicked="ProductsDisplay_LiberateClicked"/>
diff --git a/Source/LibationWinForms/AvaloniaUI/Views/MainWindow/MainWindow.axaml.cs b/Source/LibationWinForms/AvaloniaUI/Views/MainWindow/MainWindow.axaml.cs
index 58188776..ec7d15e4 100644
--- a/Source/LibationWinForms/AvaloniaUI/Views/MainWindow/MainWindow.axaml.cs
+++ b/Source/LibationWinForms/AvaloniaUI/Views/MainWindow/MainWindow.axaml.cs
@@ -20,13 +20,14 @@ namespace LibationWinForms.AvaloniaUI.Views
public MainWindow()
{
+ this.DataContext = _viewModel = new MainWindowViewModel();
+
InitializeComponent();
#if DEBUG
this.AttachDevTools();
#endif
this.FindAllControls();
- this.DataContext = _viewModel = new MainWindowViewModel();
// eg: if one of these init'd productsGrid, then another can't reliably subscribe to it
Configure_BackupCounts();
@@ -52,16 +53,19 @@ namespace LibationWinForms.AvaloniaUI.Views
this.LibraryLoaded += MainWindow_LibraryLoaded;
LibraryCommands.LibrarySizeChanged += async (_, _) => await _viewModel.ProductsDisplay.DisplayBooks(DbContexts.GetLibrary_Flat_NoTracking(includeParents: true));
- this.Closing += (_,_) => this.SaveSizeAndLocation(Configuration.Instance);
+ Closing += (_,_) => this.SaveSizeAndLocation(Configuration.Instance);
}
}
+ public void ProductsDisplay_Initialized1(object sender, EventArgs e)
+ {
+ if (sender is ProductsDisplay2 products)
+ _viewModel.ProductsDisplay.RegisterCollectionChanged(products);
+ }
+
private void MainWindow_LibraryLoaded(object sender, List dbBooks)
{
- if (Design.IsDesignMode)
- return;
-
- _viewModel.ProductsDisplay.InitialDisplay(dbBooks, productsDisplay);
+ _viewModel.ProductsDisplay.InitialDisplay(dbBooks);
}
private void InitializeComponent()
@@ -75,7 +79,6 @@ namespace LibationWinForms.AvaloniaUI.Views
private void FindAllControls()
{
quickFiltersToolStripMenuItem = this.FindControl