From 379c9be29eb6c256f1fc34c12c89ffc6c1135480 Mon Sep 17 00:00:00 2001 From: Tom Arrow Date: Mon, 25 Jan 2021 06:10:52 +0100 Subject: [PATCH] Progress in batch finally works better. --- BatchProgress.xaml.cs | 6 +-- Helpers.cs | 118 ++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 121 insertions(+), 3 deletions(-) diff --git a/BatchProgress.xaml.cs b/BatchProgress.xaml.cs index 36fea5e..5c392e9 100644 --- a/BatchProgress.xaml.cs +++ b/BatchProgress.xaml.cs @@ -24,12 +24,12 @@ public partial class BatchProgress : Window - public ObservableCollection ProgressStrings + public FullyObservableCollection ProgressStrings { get { return progressStrings; } } - public ObservableCollection progressStrings = new ObservableCollection(); + public FullyObservableCollection progressStrings = new FullyObservableCollection(); public BatchProgress() { InitializeComponent(); @@ -76,7 +76,7 @@ public void RemoveProgressItem(int id, string message="...") } } - public class ProgressItem + public class ProgressItem : INotifyPropertyChanged { public int id; public string ProgressText diff --git a/Helpers.cs b/Helpers.cs index 22bf99f..52c42b8 100644 --- a/Helpers.cs +++ b/Helpers.cs @@ -8,12 +8,130 @@ using System.IO; using System.Runtime.CompilerServices; using System.Numerics; +using System.ComponentModel; +using System.Collections.Specialized; +using System.Collections.ObjectModel; namespace ColorMatch3D { + + // This class is from: https://stackoverflow.com/questions/1427471/observablecollection-not-noticing-when-item-in-it-changes-even-with-inotifyprop + public class FullyObservableCollection : ObservableCollection + where T : INotifyPropertyChanged + { + /// + /// Occurs when a property is changed within an item. + /// + public event EventHandler ItemPropertyChanged; + + public FullyObservableCollection() : base() + { } + + public FullyObservableCollection(List list) : base(list) + { + ObserveAll(); + } + + public FullyObservableCollection(IEnumerable enumerable) : base(enumerable) + { + ObserveAll(); + } + + protected override void OnCollectionChanged(NotifyCollectionChangedEventArgs e) + { + if (e.Action == NotifyCollectionChangedAction.Remove || + e.Action == NotifyCollectionChangedAction.Replace) + { + foreach (T item in e.OldItems) + item.PropertyChanged -= ChildPropertyChanged; + } + + if (e.Action == NotifyCollectionChangedAction.Add || + e.Action == NotifyCollectionChangedAction.Replace) + { + foreach (T item in e.NewItems) + item.PropertyChanged += ChildPropertyChanged; + } + + base.OnCollectionChanged(e); + } + + protected void OnItemPropertyChanged(ItemPropertyChangedEventArgs e) + { + ItemPropertyChanged?.Invoke(this, e); + } + + protected void OnItemPropertyChanged(int index, PropertyChangedEventArgs e) + { + OnItemPropertyChanged(new ItemPropertyChangedEventArgs(index, e)); + } + + protected override void ClearItems() + { + foreach (T item in Items) + item.PropertyChanged -= ChildPropertyChanged; + + base.ClearItems(); + } + + private void ObserveAll() + { + foreach (T item in Items) + item.PropertyChanged += ChildPropertyChanged; + } + + private void ChildPropertyChanged(object sender, PropertyChangedEventArgs e) + { + T typedSender = (T)sender; + int i = Items.IndexOf(typedSender); + + if (i < 0) + throw new ArgumentException("Received property notification from item not in collection"); + + OnItemPropertyChanged(i, e); + } + } + + /// + /// Provides data for the event. + /// + public class ItemPropertyChangedEventArgs : PropertyChangedEventArgs + { + /// + /// Gets the index in the collection for which the property change has occurred. + /// + /// + /// Index in parent collection. + /// + public int CollectionIndex { get; } + + /// + /// Initializes a new instance of the class. + /// + /// The index in the collection of changed item. + /// The name of the property that changed. + public ItemPropertyChangedEventArgs(int index, string name) : base(name) + { + CollectionIndex = index; + } + + /// + /// Initializes a new instance of the class. + /// + /// The index. + /// The instance containing the event data. + public ItemPropertyChangedEventArgs(int index, PropertyChangedEventArgs args) : this(index, args.PropertyName) + { } + } + + static class Helpers { + + + + static public BitmapImage BitmapToImageSource(Bitmap bitmap) { using (MemoryStream memory = new MemoryStream())