Przeglądaj źródła

Change scenarios to use ObservableCollection.

BDisp 1 rok temu
rodzic
commit
0075c07b39

+ 4 - 3
UICatalog/KeyBindingsDialog.cs

@@ -1,5 +1,6 @@
 using System;
 using System.Collections.Generic;
+using System.Collections.ObjectModel;
 using System.Linq;
 using Terminal.Gui;
 
@@ -10,7 +11,7 @@ internal class KeyBindingsDialog : Dialog
     // TODO: Update to use Key instead of KeyCode
     private static readonly Dictionary<Command, KeyCode> CurrentBindings = new ();
 
-    private readonly Command [] _commands;
+    private readonly ObservableCollection<Command> _commands;
     private readonly ListView _commandsListView;
     private readonly Label _keyLabel;
 
@@ -26,13 +27,13 @@ internal class KeyBindingsDialog : Dialog
         }
 
         // known commands that views can support
-        _commands = Enum.GetValues (typeof (Command)).Cast<Command> ().ToArray ();
+        _commands = new (Enum.GetValues (typeof (Command)).Cast<Command> ().ToArray ());
 
         _commandsListView = new ListView
         {
             Width = Dim.Percent (50),
             Height = Dim.Percent (100) - 1,
-            Source = new ListWrapper (_commands),
+            Source = new ListWrapper<Command> (_commands),
             SelectedItem = 0
         };
 

+ 21 - 18
UICatalog/Scenario.cs

@@ -1,5 +1,6 @@
 using System;
 using System.Collections.Generic;
+using System.Collections.ObjectModel;
 using System.Linq;
 using Terminal.Gui;
 
@@ -97,7 +98,7 @@ public class Scenario : IDisposable
     ///     <see cref="ScenarioMetadata.Name"/>.
     ///     https://stackoverflow.com/questions/5411694/get-all-inherited-classes-of-an-abstract-class
     /// </summary>
-    public static List<Scenario> GetScenarios ()
+    public static ObservableCollection<Scenario> GetScenarios ()
     {
         List<Scenario> objects = new ();
 
@@ -113,7 +114,7 @@ public class Scenario : IDisposable
             _maxScenarioNameLen = Math.Max (_maxScenarioNameLen, scenario.GetName ().Length + 1);
         }
 
-        return objects.OrderBy (s => s.GetName ()).ToList ();
+        return new (objects.OrderBy (s => s.GetName ()).ToList ());
     }
 
     /// <summary>
@@ -239,24 +240,26 @@ public class Scenario : IDisposable
     #endregion IDispose
 
     /// <summary>Returns a list of all Categories set by all of the <see cref="Scenario"/>s defined in the project.</summary>
-    internal static List<string> GetAllCategories ()
+    internal static ObservableCollection<string> GetAllCategories ()
     {
-        List<string> categories = new ();
-
-        categories = typeof (Scenario).Assembly.GetTypes ()
-                                      .Where (
-                                              myType => myType.IsClass
-                                                        && !myType.IsAbstract
-                                                        && myType.IsSubclassOf (typeof (Scenario)))
-                                      .Select (type => System.Attribute.GetCustomAttributes (type).ToList ())
-                                      .Aggregate (
-                                                  categories,
-                                                  (current, attrs) => current
-                                                                      .Union (attrs.Where (a => a is ScenarioCategory).Select (a => ((ScenarioCategory)a).Name))
-                                                                      .ToList ());
+        List<string> aCategories = [];
+
+        aCategories = typeof (Scenario).Assembly.GetTypes ()
+                                       .Where (
+                                               myType => myType.IsClass
+                                                         && !myType.IsAbstract
+                                                         && myType.IsSubclassOf (typeof (Scenario)))
+                                       .Select (type => System.Attribute.GetCustomAttributes (type).ToList ())
+                                       .Aggregate (
+                                                   aCategories,
+                                                   (current, attrs) => current
+                                                                       .Union (
+                                                                               attrs.Where (a => a is ScenarioCategory)
+                                                                                    .Select (a => ((ScenarioCategory)a).Name))
+                                                                       .ToList ());
 
         // Sort
-        categories = categories.OrderBy (c => c).ToList ();
+        ObservableCollection<string> categories = new (aCategories.OrderBy (c => c).ToList ());
 
         // Put "All" at the top
         categories.Insert (0, "All Scenarios");
@@ -264,7 +267,7 @@ public class Scenario : IDisposable
         return categories;
     }
 
-    /// <summary>Defines the category names used to catagorize a <see cref="Scenario"/></summary>
+    /// <summary>Defines the category names used to categorize a <see cref="Scenario"/></summary>
     [AttributeUsage (AttributeTargets.Class, AllowMultiple = true)]
     public class ScenarioCategory (string Name) : System.Attribute
     {

+ 4 - 3
UICatalog/Scenarios/AllViewsTester.cs

@@ -1,5 +1,6 @@
 using System;
 using System.Collections.Generic;
+using System.Collections.ObjectModel;
 using System.Linq;
 using System.Reflection;
 using Terminal.Gui;
@@ -80,7 +81,7 @@ public class AllViewsTester : Scenario
             AllowsMarking = false,
             ColorScheme = Colors.ColorSchemes ["TopLevel"],
             SelectedItem = 0,
-            Source = new ListWrapper (_viewClasses.Keys.ToList ())
+            Source = new ListWrapper<string> (new (_viewClasses.Keys.ToList ()))
         };
         _classListView.OpenSelectedItem += (s, a) => { _settingsPane.SetFocus (); };
 
@@ -385,8 +386,8 @@ public class AllViewsTester : Scenario
         // If the view supports a Source property, set it so we have something to look at
         if (view != null && view.GetType ().GetProperty ("Source") != null && view.GetType ().GetProperty ("Source").PropertyType == typeof (IListDataSource))
         {
-            var source = new ListWrapper (new List<string> { "Test Text #1", "Test Text #2", "Test Text #3" });
-            view?.GetType ().GetProperty ("Source")?.GetSetMethod ()?.Invoke (view, new [] { source });
+            var source = new ListWrapper<string> (["Test Text #1", "Test Text #2", "Test Text #3"]);
+            view?.GetType ().GetProperty ("Source")?.GetSetMethod ()?.Invoke (view, [source]);
         }
 
         // If the view supports a Title property, set it so we have something to look at

+ 5 - 4
UICatalog/Scenarios/BackgroundWorkerCollection.cs

@@ -1,5 +1,6 @@
 using System;
 using System.Collections.Generic;
+using System.Collections.ObjectModel;
 using System.ComponentModel;
 using System.Diagnostics;
 using System.Threading;
@@ -247,7 +248,7 @@ public class BackgroundWorkerCollection : Scenario
         private readonly ListView _listView;
         private readonly Button _start;
 
-        public StagingUIController (Staging staging, List<string> list) : this ()
+        public StagingUIController (Staging staging, ObservableCollection<string> list) : this ()
         {
             Staging = staging;
             _label.Text = "Work list:";
@@ -335,7 +336,7 @@ public class BackgroundWorkerCollection : Scenario
     private class WorkerApp : Toplevel
     {
         private readonly ListView _listLog;
-        private readonly List<string> _log = [];
+        private readonly ObservableCollection<string> _log = [];
         private List<StagingUIController> _stagingsUi;
         private Dictionary<Staging, BackgroundWorker> _stagingWorkers;
 
@@ -357,7 +358,7 @@ public class BackgroundWorkerCollection : Scenario
                 Y = 0,
                 Width = Dim.Fill (),
                 Height = Dim.Fill (),
-                Source = new ListWrapper (_log)
+                Source = new ListWrapper<string> (_log)
             };
             Add (_listLog);
 
@@ -464,7 +465,7 @@ public class BackgroundWorkerCollection : Scenario
                                                           );
                                                  Application.Refresh ();
 
-                                                 var stagingUI = new StagingUIController (staging, e.Result as List<string>)
+                                                 var stagingUI = new StagingUIController (staging, e.Result as ObservableCollection<string>)
                                                  {
                                                      Modal = false,
                                                      Title =

+ 4 - 3
UICatalog/Scenarios/CollectionNavigatorTester.cs

@@ -1,5 +1,6 @@
 using System;
 using System.Collections.Generic;
+using System.Collections.ObjectModel;
 using System.Linq;
 using Terminal.Gui;
 
@@ -16,7 +17,7 @@ namespace UICatalog.Scenarios;
 [ScenarioCategory ("Mouse and Keyboard")]
 public class CollectionNavigatorTester : Scenario
 {
-    private readonly List<string> _items = new []
+    private ObservableCollection<string> _items = new ObservableCollection<string> (new ObservableCollection<string> ()
     {
         "a",
         "b",
@@ -71,7 +72,7 @@ public class CollectionNavigatorTester : Scenario
         "q",
         "quit",
         "quitter"
-    }.ToList ();
+    }.ToList ());
 
     private ListView _listView;
     private TreeView _treeView;
@@ -129,7 +130,7 @@ public class CollectionNavigatorTester : Scenario
 
         Top.Add (menu);
 
-        _items.Sort (StringComparer.OrdinalIgnoreCase);
+        _items = new (_items.OrderBy (i => i, StringComparer.OrdinalIgnoreCase));
 
         CreateListView ();
         var vsep = new LineView (Orientation.Vertical) { X = Pos.Right (_listView), Y = 1, Height = Dim.Fill () };

+ 5 - 4
UICatalog/Scenarios/ComboBoxIteration.cs

@@ -1,4 +1,5 @@
 using System.Collections.Generic;
+using System.Collections.ObjectModel;
 using Terminal.Gui;
 
 namespace UICatalog.Scenarios;
@@ -10,14 +11,14 @@ public class ComboBoxIteration : Scenario
 {
     public override void Setup ()
     {
-        List<string> items = new () { "one", "two", "three" };
+        ObservableCollection<string> items = ["one", "two", "three"];
 
         var lbListView = new Label { Width = 10, Height = 1 };
         Win.Add (lbListView);
 
         var listview = new ListView
         {
-            Y = Pos.Bottom (lbListView) + 1, Width = 10, Height = Dim.Fill (2), Source = new ListWrapper (items)
+            Y = Pos.Bottom (lbListView) + 1, Width = 10, Height = Dim.Fill (2), Source = new ListWrapper<string> (items)
         };
         Win.Add (listview);
 
@@ -59,7 +60,7 @@ public class ComboBoxIteration : Scenario
 
         btnTwo.Accept += (s, e) =>
                           {
-                              items = new List<string> { "one", "two" };
+                              items = ["one", "two"];
                               comboBox.SetSource (items);
                               listview.SetSource (items);
                               listview.SelectedItem = 0;
@@ -70,7 +71,7 @@ public class ComboBoxIteration : Scenario
 
         btnThree.Accept += (s, e) =>
                             {
-                                items = new List<string> { "one", "two", "three" };
+                                items =["one", "two", "three"];
                                 comboBox.SetSource (items);
                                 listview.SetSource (items);
                                 listview.SelectedItem = 0;

+ 16 - 17
UICatalog/Scenarios/DynamicMenuBar.cs

@@ -1,6 +1,5 @@
 using System;
-using System.Collections;
-using System.Collections.Generic;
+using System.Collections.ObjectModel;
 using System.ComponentModel;
 using System.Reflection;
 using System.Runtime.CompilerServices;
@@ -440,7 +439,7 @@ public class DynamicMenuBar : Scenario
                                     TextTitle.Text = string.Empty;
                                     Application.RequestStop ();
                                 };
-            var dialog = new Dialog { Title = "Enter the menu details.", Buttons = [btnOk, btnCancel] };
+            var dialog = new Dialog { Title = "Enter the menu details.", Buttons = [btnOk, btnCancel], Height = Dim.Auto (DimAutoStyle.Content, 22, Driver.Rows) };
 
             Width = Dim.Fill ();
             Height = Dim.Fill () - 1;
@@ -596,10 +595,10 @@ public class DynamicMenuBar : Scenario
             var _btnAddMenuBar = new Button { Y = 1, Text = "Add a MenuBar" };
             _frmMenu.Add (_btnAddMenuBar);
 
-            var _btnMenuBarUp = new Button { X = Pos.Center (), Text = "^" };
+            var _btnMenuBarUp = new Button { X = Pos.Center (), Text = CM.Glyphs.UpArrow.ToString () };
             _frmMenu.Add (_btnMenuBarUp);
 
-            var _btnMenuBarDown = new Button { X = Pos.Center (), Y = Pos.Bottom (_btnMenuBarUp), Text = "v" };
+            var _btnMenuBarDown = new Button { X = Pos.Center (), Y = Pos.Bottom (_btnMenuBarUp), Text = CM.Glyphs.DownArrow.ToString () };
             _frmMenu.Add (_btnMenuBarDown);
 
             var _btnRemoveMenuBar = new Button { Y = 1, Text = "Remove a MenuBar" };
@@ -609,7 +608,7 @@ public class DynamicMenuBar : Scenario
 
             var _btnPrevious = new Button
             {
-                X = Pos.Left (_btnAddMenuBar), Y = Pos.Top (_btnAddMenuBar) + 2, Text = "<"
+                X = Pos.Left (_btnAddMenuBar), Y = Pos.Top (_btnAddMenuBar) + 2, Text = CM.Glyphs.LeftArrow.ToString ()
             };
             _frmMenu.Add (_btnPrevious);
 
@@ -617,7 +616,7 @@ public class DynamicMenuBar : Scenario
             _btnAdd.X = Pos.AnchorEnd ();
             _frmMenu.Add (_btnAdd);
 
-            var _btnNext = new Button { X = Pos.X (_btnAdd), Y = Pos.Top (_btnPrevious), Text = ">" };
+            var _btnNext = new Button { X = Pos.X (_btnAdd), Y = Pos.Top (_btnPrevious), Text = CM.Glyphs.RightArrow.ToString () };
             _frmMenu.Add (_btnNext);
 
             var _lblMenuBar = new Label
@@ -657,7 +656,7 @@ public class DynamicMenuBar : Scenario
                 Y = Pos.Top (_btnPrevious) + 2,
                 Width = _lblMenuBar.Width,
                 Height = Dim.Fill (),
-                Source = new ListWrapper (new List<DynamicMenuItemList> ())
+                Source = new ListWrapper<DynamicMenuItemList> ([])
             };
             _frmMenu.Add (_lstMenus);
 
@@ -669,10 +668,10 @@ public class DynamicMenuBar : Scenario
             var _btnRemove = new Button { X = Pos.Left (_btnAdd), Y = Pos.Top (_btnAdd) + 1, Text = "Remove" };
             _frmMenu.Add (_btnRemove);
 
-            var _btnUp = new Button { X = Pos.Right (_lstMenus) + 2, Y = Pos.Top (_btnRemove) + 2, Text = "^" };
+            var _btnUp = new Button { X = Pos.Right (_lstMenus) + 2, Y = Pos.Top (_btnRemove) + 2, Text = CM.Glyphs.UpArrow.ToString () };
             _frmMenu.Add (_btnUp);
 
-            var _btnDown = new Button { X = Pos.Right (_lstMenus) + 2, Y = Pos.Top (_btnUp) + 1, Text = "v" };
+            var _btnDown = new Button { X = Pos.Right (_lstMenus) + 2, Y = Pos.Top (_btnUp) + 1, Text = CM.Glyphs.DownArrow.ToString () };
             _frmMenu.Add (_btnDown);
 
             Add (_frmMenu);
@@ -857,7 +856,7 @@ public class DynamicMenuBar : Scenario
                                       return;
                                   }
 
-                                  if (!(_currentMenuBarItem is MenuBarItem))
+                                  if (_currentMenuBarItem is not MenuBarItem)
                                   {
                                       var parent = _currentMenuBarItem.Parent as MenuBarItem;
                                       int idx = parent.GetChildrenIndex (_currentMenuBarItem);
@@ -1109,7 +1108,7 @@ public class DynamicMenuBar : Scenario
             SetFrameDetails ();
 
             var ustringConverter = new UStringValueConverter ();
-            var listWrapperConverter = new ListWrapperConverter ();
+            var listWrapperConverter = new ListWrapperConverter<DynamicMenuItemList> ();
 
             var lblMenuBar = new Binding (this, "MenuBar", _lblMenuBar, "Text", ustringConverter);
             var lblParent = new Binding (this, "Parent", _lblParent, "Text", ustringConverter);
@@ -1160,7 +1159,7 @@ public class DynamicMenuBar : Scenario
 
             void SetListViewSource (MenuItem _currentMenuBarItem, bool fill = false)
             {
-                DataContext.Menus = new ();
+                DataContext.Menus = [];
                 var menuBarItem = _currentMenuBarItem as MenuBarItem;
 
                 if (menuBarItem != null && menuBarItem?.Children == null)
@@ -1344,7 +1343,7 @@ public class DynamicMenuBar : Scenario
     public class DynamicMenuItemModel : INotifyPropertyChanged
     {
         private string _menuBar;
-        private List<DynamicMenuItemList> _menus;
+        private ObservableCollection<DynamicMenuItemList> _menus;
         private string _parent;
         public DynamicMenuItemModel () { Menus = []; }
 
@@ -1367,7 +1366,7 @@ public class DynamicMenuBar : Scenario
             }
         }
 
-        public List<DynamicMenuItemList> Menus
+        public ObservableCollection<DynamicMenuItemList> Menus
         {
             get => _menus;
             set
@@ -1414,9 +1413,9 @@ public class DynamicMenuBar : Scenario
         object Convert (object value, object parameter = null);
     }
 
-    public class ListWrapperConverter : IValueConverter
+    public class ListWrapperConverter<T> : IValueConverter
     {
-        public object Convert (object value, object parameter = null) { return new ListWrapper ((IList)value); }
+        public object Convert (object value, object parameter = null) { return new ListWrapper<T> ((ObservableCollection<T>)value); }
     }
 
     public class UStringValueConverter : IValueConverter

+ 14 - 16
UICatalog/Scenarios/DynamicStatusBar.cs

@@ -1,6 +1,5 @@
 using System;
-using System.Collections;
-using System.Collections.Generic;
+using System.Collections.ObjectModel;
 using System.ComponentModel;
 using System.Reflection;
 using System.Runtime.CompilerServices;
@@ -284,7 +283,7 @@ public class DynamicStatusBar : Scenario
                                       TextTitle.Text = string.Empty;
                                       Application.RequestStop ();
                                   };
-            var dialog = new Dialog { Title = "Enter the menu details.", Buttons = [btnOk, btnCancel] };
+            var dialog = new Dialog { Title = "Enter the menu details.", Buttons = [btnOk, btnCancel], Height = Dim.Auto (DimAutoStyle.Content, 17, Driver.Rows) };
 
             Width = Dim.Fill ();
             Height = Dim.Fill () - 1;
@@ -375,7 +374,7 @@ public class DynamicStatusBar : Scenario
             _frmStatusBar.Add (_btnRemoveStatusBar);
 
             var _btnAdd = new Button { Y = Pos.Top (_btnRemoveStatusBar) + 2, Text = " Add  " };
-            _btnAdd.X = Pos.AnchorEnd (0);
+            _btnAdd.X = Pos.AnchorEnd ();
             _frmStatusBar.Add (_btnAdd);
 
             _lstItems = new ListView
@@ -384,17 +383,17 @@ public class DynamicStatusBar : Scenario
                 Y = Pos.Top (_btnAddStatusBar) + 2,
                 Width = Dim.Fill () - Dim.Width (_btnAdd) - 1,
                 Height = Dim.Fill (),
-                Source = new ListWrapper (new List<DynamicStatusItemList> ())
+                Source = new ListWrapper<DynamicStatusItemList> ([])
             };
             _frmStatusBar.Add (_lstItems);
 
             var _btnRemove = new Button { X = Pos.Left (_btnAdd), Y = Pos.Top (_btnAdd) + 1, Text = "Remove" };
             _frmStatusBar.Add (_btnRemove);
 
-            var _btnUp = new Button { X = Pos.Right (_lstItems) + 2, Y = Pos.Top (_btnRemove) + 2, Text = "^" };
+            var _btnUp = new Button { X = Pos.Right (_lstItems) + 2, Y = Pos.Top (_btnRemove) + 2, Text = CM.Glyphs.UpArrow.ToString () };
             _frmStatusBar.Add (_btnUp);
 
-            var _btnDown = new Button { X = Pos.Right (_lstItems) + 2, Y = Pos.Top (_btnUp) + 1, Text = "v" };
+            var _btnDown = new Button { X = Pos.Right (_lstItems) + 2, Y = Pos.Top (_btnUp) + 1, Text = CM.Glyphs.DownArrow.ToString () };
             _frmStatusBar.Add (_btnDown);
 
             Add (_frmStatusBar);
@@ -569,7 +568,7 @@ public class DynamicStatusBar : Scenario
 
                                                Remove (_statusBar);
                                                _statusBar = null;
-                                               DataContext.Items = new List<DynamicStatusItemList> ();
+                                               DataContext.Items = [];
                                                _currentStatusItem = null;
                                                _currentSelectedStatusBar = -1;
                                                SetListViewSource (_currentStatusItem, true);
@@ -579,7 +578,7 @@ public class DynamicStatusBar : Scenario
             SetFrameDetails ();
 
             var ustringConverter = new UStringValueConverter ();
-            var listWrapperConverter = new ListWrapperConverter ();
+            var listWrapperConverter = new ListWrapperConverter<DynamicStatusItemList> ();
 
             var lstItems = new Binding (this, "Items", _lstItems, "Source", listWrapperConverter);
 
@@ -611,7 +610,7 @@ public class DynamicStatusBar : Scenario
 
             void SetListViewSource (StatusItem _currentStatusItem, bool fill = false)
             {
-                DataContext.Items = new List<DynamicStatusItemList> ();
+                DataContext.Items = [];
                 StatusItem statusItem = _currentStatusItem;
 
                 if (!fill)
@@ -681,10 +680,9 @@ public class DynamicStatusBar : Scenario
             if (split.Length > 1)
             {
                 txt = split [2].Trim ();
-                ;
             }
 
-            if (string.IsNullOrEmpty (shortcut))
+            if (string.IsNullOrEmpty (shortcut) || shortcut == "Null")
             {
                 return txt;
             }
@@ -717,11 +715,11 @@ public class DynamicStatusBar : Scenario
 
     public class DynamicStatusItemModel : INotifyPropertyChanged
     {
-        private List<DynamicStatusItemList> _items;
+        private ObservableCollection<DynamicStatusItemList> _items;
         private string _statusBar;
         public DynamicStatusItemModel () { Items = []; }
 
-        public List<DynamicStatusItemList> Items
+        public ObservableCollection<DynamicStatusItemList> Items
         {
             get => _items;
             set
@@ -768,9 +766,9 @@ public class DynamicStatusBar : Scenario
         object Convert (object value, object parameter = null);
     }
 
-    public class ListWrapperConverter : IValueConverter
+    public class ListWrapperConverter<T> : IValueConverter
     {
-        public object Convert (object value, object parameter = null) { return new ListWrapper ((IList)value); }
+        public object Convert (object value, object parameter = null) { return new ListWrapper<T> ((ObservableCollection<T>)value); }
     }
 
     public class UStringValueConverter : IValueConverter

+ 7 - 7
UICatalog/Scenarios/Keys.cs

@@ -1,4 +1,4 @@
-using System.Collections.Generic;
+using System.Collections.ObjectModel;
 using Terminal.Gui;
 
 namespace UICatalog.Scenarios;
@@ -9,8 +9,8 @@ public class Keys : Scenario
 {
     public override void Setup ()
     {
-        List<string> keyPressedList = new ();
-        List<string> invokingKeyBindingsList = new ();
+        ObservableCollection<string> keyPressedList = [];
+        ObservableCollection<string> invokingKeyBindingsList = new ();
 
         var editLabel = new Label { X = 0, Y = 0, Text = "Type text here:" };
         Win.Add (editLabel);
@@ -57,7 +57,7 @@ public class Keys : Scenario
         Win.Add (keyLogLabel);
         int maxKeyString = Key.CursorRight.WithAlt.WithCtrl.WithShift.ToString ().Length;
         var yOffset = 1;
-        List<string> keyEventlist = new ();
+        ObservableCollection<string> keyEventlist = new ();
 
         var keyEventListView = new ListView
         {
@@ -65,7 +65,7 @@ public class Keys : Scenario
             Y = Pos.Top (keyLogLabel) + yOffset,
             Width = "Key Down:".Length + maxKeyString,
             Height = Dim.Fill (),
-            Source = new ListWrapper (keyEventlist)
+            Source = new ListWrapper<string> (keyEventlist)
         };
         keyEventListView.ColorScheme = Colors.ColorSchemes ["TopLevel"];
         Win.Add (keyEventListView);
@@ -85,7 +85,7 @@ public class Keys : Scenario
             Y = Pos.Top (onKeyPressedLabel) + yOffset,
             Width = maxKeyString,
             Height = Dim.Fill (),
-            Source = new ListWrapper (keyPressedList)
+            Source = new ListWrapper<string> (keyPressedList)
         };
         onKeyPressedListView.ColorScheme = Colors.ColorSchemes ["TopLevel"];
         Win.Add (onKeyPressedListView);
@@ -105,7 +105,7 @@ public class Keys : Scenario
             Y = Pos.Top (onInvokingKeyBindingsLabel) + yOffset,
             Width = Dim.Fill (1),
             Height = Dim.Fill (),
-            Source = new ListWrapper (invokingKeyBindingsList)
+            Source = new ListWrapper<string> (invokingKeyBindingsList)
         };
         onInvokingKeyBindingsListView.ColorScheme = Colors.ColorSchemes ["TopLevel"];
         Win.Add (onInvokingKeyBindingsListView);

+ 8 - 4
UICatalog/Scenarios/ListViewWithSelection.cs

@@ -1,5 +1,7 @@
 using System.Collections;
 using System.Collections.Generic;
+using System.Collections.ObjectModel;
+using System.Collections.Specialized;
 using System.Text;
 using JetBrains.Annotations;
 using Terminal.Gui;
@@ -15,7 +17,7 @@ public class ListViewWithSelection : Scenario
     public CheckBox _allowMultipleCB;
     public CheckBox _customRenderCB;
     public ListView _listView;
-    public List<Scenario> _scenarios;
+    public ObservableCollection<Scenario> _scenarios;
 
     public override void Setup ()
     {
@@ -160,10 +162,10 @@ public class ListViewWithSelection : Scenario
         private readonly int _nameColumnWidth = 30;
         private int count;
         private BitArray marks;
-        private List<Scenario> scenarios;
-        public ScenarioListDataSource (List<Scenario> itemList) { Scenarios = itemList; }
+        private ObservableCollection<Scenario> scenarios;
+        public ScenarioListDataSource (ObservableCollection<Scenario> itemList) { Scenarios = itemList; }
 
-        public List<Scenario> Scenarios
+        public ObservableCollection<Scenario> Scenarios
         {
             get => scenarios;
             set
@@ -188,6 +190,8 @@ public class ListViewWithSelection : Scenario
             return false;
         }
 
+        /// <inheritdoc />
+        public event NotifyCollectionChangedEventHandler CollectionChanged;
         public int Count => Scenarios != null ? Scenarios.Count : 0;
         public int Length { get; private set; }
 

+ 10 - 10
UICatalog/Scenarios/ListsAndCombos.cs

@@ -1,5 +1,5 @@
 using System;
-using System.Collections.Generic;
+using System.Collections.ObjectModel;
 using System.IO;
 using System.Linq;
 using Terminal.Gui;
@@ -15,19 +15,19 @@ public class ListsAndCombos : Scenario
     public override void Setup ()
     {
         //TODO: Duplicated code in Demo.cs Consider moving to shared assembly
-        List<string> items = new ();
+        ObservableCollection<string> items = [];
 
         foreach (string dir in new [] { "/etc", @$"{Environment.GetEnvironmentVariable ("SystemRoot")}\System32" })
         {
             if (Directory.Exists (dir))
             {
-                items = Directory.GetFiles (dir)
-                                 .Union (Directory.GetDirectories (dir))
-                                 .Select (Path.GetFileName)
-                                 .Where (x => char.IsLetterOrDigit (x [0]))
-                                 .OrderBy (x => x)
-                                 .Select (x => x)
-                                 .ToList ();
+                items = new (Directory.GetFiles (dir)
+                                      .Union (Directory.GetDirectories (dir))
+                                      .Select (Path.GetFileName)
+                                      .Where (x => char.IsLetterOrDigit (x [0]))
+                                      .OrderBy (x => x)
+                                      .Select (x => x)
+                                      .ToList ());
             }
         }
 
@@ -47,7 +47,7 @@ public class ListsAndCombos : Scenario
             Y = Pos.Bottom (lbListView) + 1,
             Height = Dim.Fill (2),
             Width = Dim.Percent (40),
-            Source = new ListWrapper (items)
+            Source = new ListWrapper<string> (items)
         };
         listview.SelectedItemChanged += (s, e) => lbListView.Text = items [listview.SelectedItem];
         Win.Add (lbListView, listview);

+ 2 - 2
UICatalog/Scenarios/Localization.cs

@@ -112,10 +112,10 @@ public class Localization : Scenario
             Width = _cultureInfoNameSource.Select (cn => cn.Length + 3).Max (),
             Height = _cultureInfoNameSource.Length + 1,
             HideDropdownListOnClick = true,
-            Source = new ListWrapper (_cultureInfoNameSource),
+            Source = new ListWrapper<string> (new (_cultureInfoNameSource)),
             SelectedItem = _cultureInfoNameSource.Length - 1
         };
-        _languageComboBox.SetSource (_cultureInfoNameSource);
+        _languageComboBox.SetSource<string> (new (_cultureInfoNameSource));
         _languageComboBox.SelectedItemChanged += LanguageComboBox_SelectChanged;
         Win.Add (_languageComboBox);
 

+ 5 - 5
UICatalog/Scenarios/Mouse.cs

@@ -1,5 +1,5 @@
 using System;
-using System.Collections.Generic;
+using System.Collections.ObjectModel;
 using System.Linq;
 using Terminal.Gui;
 
@@ -113,7 +113,7 @@ public class Mouse : Scenario
             Y = Pos.Bottom (demo)
         };
 
-        List<string> appLogList = new ();
+        ObservableCollection<string> appLogList = new ();
 
         var appLog = new ListView
         {
@@ -122,7 +122,7 @@ public class Mouse : Scenario
             Width = 50,
             Height = Dim.Fill (),
             ColorScheme = Colors.ColorSchemes ["TopLevel"],
-            Source = new ListWrapper (appLogList)
+            Source = new ListWrapper<string> (appLogList)
         };
         win.Add (label, appLog);
 
@@ -144,7 +144,7 @@ public class Mouse : Scenario
             X = Pos.Right (appLog) + 1,
             Y = Pos.Top (label)
         };
-        List<string> winLogList = new ();
+        ObservableCollection<string> winLogList = new ();
 
         var winLog = new ListView
         {
@@ -153,7 +153,7 @@ public class Mouse : Scenario
             Width = Dim.Percent (50),
             Height = Dim.Fill (),
             ColorScheme = Colors.ColorSchemes ["TopLevel"],
-            Source = new ListWrapper (winLogList)
+            Source = new ListWrapper<string> (winLogList)
         };
         win.Add (label, winLog);
 

+ 5 - 3
UICatalog/Scenarios/ProgressBarStyles.cs

@@ -1,6 +1,7 @@
 using System;
 using System.Collections;
 using System.Collections.Generic;
+using System.Collections.ObjectModel;
 using System.Linq;
 using System.Threading;
 using Terminal.Gui;
@@ -261,9 +262,10 @@ public class ProgressBarStyles : Scenario
         container.Add (marqueesContinuousPB);
 
         _pbList.SetSource (
-                          container.Subviews.Where (v => v.GetType () == typeof (ProgressBar))
-                                   .Select (v => v.Title)
-                                   .ToList ()
+                          new ObservableCollection<string> (
+                                                            container.Subviews.Where (v => v.GetType () == typeof (ProgressBar))
+                                                                     .Select (v => v.Title)
+                                                                     .ToList ())
                          );
 
         _pbList.SelectedItemChanged += (sender, e) =>

+ 6 - 6
UICatalog/Scenarios/SingleBackgroundWorker.cs

@@ -1,7 +1,7 @@
 using System;
 using System.Collections.Generic;
+using System.Collections.ObjectModel;
 using System.ComponentModel;
-using System.Diagnostics;
 using System.Threading;
 using Terminal.Gui;
 
@@ -24,7 +24,7 @@ public class SingleBackgroundWorker : Scenario
     public class MainApp : Toplevel
     {
         private readonly ListView _listLog;
-        private readonly List<string> _log = new ();
+        private readonly ObservableCollection<string> _log = [];
         private DateTime? _startStaging;
         private BackgroundWorker _worker;
 
@@ -90,7 +90,7 @@ public class SingleBackgroundWorker : Scenario
                 Y = 2,
                 Width = Dim.Fill (),
                 Height = Dim.Fill (),
-                Source = new ListWrapper (_log)
+                Source = new ListWrapper<string> (_log)
             };
             workerLogTop.Add (_listLog);
             Add (workerLogTop);
@@ -194,7 +194,7 @@ public class SingleBackgroundWorker : Scenario
                                                   Application.Refresh ();
 
                                                   var builderUI =
-                                                      new StagingUIController (_startStaging, e.Result as List<string>);
+                                                      new StagingUIController (_startStaging, e.Result as ObservableCollection<string>);
                                                   var top = Application.Top;
                                                   top.Visible = false;
                                                   Application.Current.Visible = false;
@@ -215,7 +215,7 @@ public class SingleBackgroundWorker : Scenario
     {
         private Toplevel _top;
 
-        public StagingUIController (DateTime? start, List<string> list)
+        public StagingUIController (DateTime? start, ObservableCollection<string> list)
         {
             _top = new Toplevel
             {
@@ -302,7 +302,7 @@ public class SingleBackgroundWorker : Scenario
                      Y = 0,
                      Width = Dim.Fill (),
                      Height = Dim.Fill (),
-                     Source = new ListWrapper (list)
+                     Source = new ListWrapper<string> (list)
                  }
                 );
 

+ 2 - 1
UICatalog/Scenarios/SpinnerStyles.cs

@@ -1,5 +1,6 @@
 using System;
 using System.Collections.Generic;
+using System.Collections.ObjectModel;
 using System.Linq;
 using Terminal.Gui;
 
@@ -116,7 +117,7 @@ public class SpinnerViewStyles : Scenario
         {
             X = Pos.Center (), Y = Pos.Bottom (preview) + 2, Height = Dim.Fill (), Width = Dim.Fill (1)
         };
-        styles.SetSource (styleArray);
+        styles.SetSource (new ObservableCollection<string> (styleArray));
         styles.SelectedItem = 0; // SpinnerStyle.Custom;
         app.Add (styles);
         SetCustom ();

+ 11 - 11
UICatalog/Scenarios/Threading.cs

@@ -1,5 +1,5 @@
 using System;
-using System.Collections.Generic;
+using System.Collections.ObjectModel;
 using System.Threading;
 using System.Threading.Tasks;
 using Terminal.Gui;
@@ -10,7 +10,7 @@ namespace UICatalog.Scenarios;
 [ScenarioCategory ("Threading")]
 public class Threading : Scenario
 {
-    private readonly List<string> _log = [];
+    private readonly ObservableCollection<string> _log = [];
     private Action _action;
     private Button _btnActionCancel;
     private CancellationTokenSource _cancellationTokenSource;
@@ -28,7 +28,7 @@ public class Threading : Scenario
                   {
                       _itemsList.Source = null;
                       LogJob ("Loading task lambda");
-                      List<string> items = await LoadDataAsync ();
+                      ObservableCollection<string> items = await LoadDataAsync ();
                       LogJob ("Returning from task lambda");
                       await _itemsList.SetSourceAsync (items);
                   };
@@ -37,7 +37,7 @@ public class Threading : Scenario
                    {
                        _itemsList.Source = null;
                        LogJob ("Loading task handler");
-                       List<string> items = await LoadDataAsync ();
+                       ObservableCollection<string> items = await LoadDataAsync ();
                        LogJob ("Returning from task handler");
                        await _itemsList.SetSourceAsync (items);
                    };
@@ -47,7 +47,7 @@ public class Threading : Scenario
                     _itemsList.Source = null;
                     LogJob ("Loading task synchronous");
 
-                    List<string> items =
+                    ObservableCollection<string> items =
                         ["One", "Two", "Three", "Four", "Five", "Six", "Seven", "Eight", "Nine", "Ten"];
                     LogJob ("Returning from task synchronous");
                     _itemsList.SetSource (items);
@@ -76,7 +76,7 @@ public class Threading : Scenario
             Width = 50,
             Height = Dim.Fill (),
             ColorScheme = Colors.ColorSchemes ["TopLevel"],
-            Source = new ListWrapper (_log)
+            Source = new ListWrapper<string> (_log)
         };
 
         var text = new TextField { X = 1, Y = 3, Width = 100, Text = "Type anything after press the button" };
@@ -148,7 +148,7 @@ public class Threading : Scenario
             }
 
             LogJob ($"Calling task Thread:{Thread.CurrentThread.ManagedThreadId} {DateTime.Now}");
-            List<string> items = await Task.Run (LoadItemsAsync, _cancellationTokenSource.Token);
+            ObservableCollection<string> items = await Task.Run (LoadItemsAsync, _cancellationTokenSource.Token);
 
             if (!_cancellationTokenSource.IsCancellationRequested)
             {
@@ -177,12 +177,12 @@ public class Threading : Scenario
     {
         _itemsList.Source = null;
         LogJob ("Loading task");
-        List<string> items = await LoadDataAsync ();
+        ObservableCollection<string> items = await LoadDataAsync ();
         LogJob ("Returning from task");
         await _itemsList.SetSourceAsync (items);
     }
 
-    private async Task<List<string>> LoadDataAsync ()
+    private async Task<ObservableCollection<string>> LoadDataAsync ()
     {
         _itemsList.Source = null;
         LogJob ("Starting delay");
@@ -211,7 +211,7 @@ public class Threading : Scenario
         ];
     }
 
-    private async Task<List<string>> LoadItemsAsync ()
+    private async Task<ObservableCollection<string>> LoadItemsAsync ()
     {
         // Do something that takes lot of times.
         LogJob ($"Starting delay Thread:{Thread.CurrentThread.ManagedThreadId} {DateTime.Now}");
@@ -231,7 +231,7 @@ public class Threading : Scenario
     {
         _itemsList.Source = null;
         LogJob ("Loading task method");
-        List<string> items = ["One", "Two", "Three", "Four", "Five", "Six", "Seven", "Eight", "Nine", "Ten"];
+        ObservableCollection<string> items = ["One", "Two", "Three", "Four", "Five", "Six", "Seven", "Eight", "Nine", "Ten"];
         await Task.Delay (3000);
         LogJob ("Returning from task method");
         await _itemsList.SetSourceAsync (items);

+ 5 - 5
UICatalog/Scenarios/Unicode.cs

@@ -1,4 +1,4 @@
-using System.Collections.Generic;
+using System.Collections.ObjectModel;
 using System.IO;
 using System.Text;
 using Terminal.Gui;
@@ -140,7 +140,7 @@ public class UnicodeInMenu : Scenario
         label = new() { X = Pos.X (label), Y = Pos.Bottom (checkBoxRight) + 1, Text = "ComboBox:" };
         Win.Add (label);
         var comboBox = new ComboBox { X = 20, Y = Pos.Y (label), Width = Dim.Percent (50) };
-        comboBox.SetSource (new List<string> { gitString, "Со_хранить" });
+        comboBox.SetSource (new ObservableCollection<string> { gitString, "Со_хранить" });
 
         Win.Add (comboBox);
         comboBox.Text = gitString;
@@ -163,9 +163,9 @@ public class UnicodeInMenu : Scenario
             Y = Pos.Y (label),
             Width = Dim.Percent (60),
             Height = 3,
-            Source = new ListWrapper (
-                                      new List<string> { "item #1", gitString, "Со_хранить", unicode }
-                                     )
+            Source = new ListWrapper<string> (
+                                              ["item #1", gitString, "Со_хранить", unicode]
+                                             )
         };
         Win.Add (listView);
 

+ 12 - 11
UICatalog/UICatalog.cs

@@ -2,6 +2,7 @@ global using Attribute = Terminal.Gui.Attribute;
 global using CM = Terminal.Gui.ConfigurationManager;
 using System;
 using System.Collections.Generic;
+using System.Collections.ObjectModel;
 using System.CommandLine;
 using System.Diagnostics;
 using System.Globalization;
@@ -54,14 +55,14 @@ internal class UICatalogApp
     // main app UI can be restored to previous state
     private static int _cachedScenarioIndex;
     private static string? _cachedTheme = string.Empty;
-    private static List<string>? _categories;
+    private static ObservableCollection<string>? _categories;
     private static readonly FileSystemWatcher _currentDirWatcher = new ();
     private static ViewDiagnosticFlags _diagnosticFlags;
     private static string _forceDriver = string.Empty;
     private static readonly FileSystemWatcher _homeDirWatcher = new ();
     private static bool _isFirstRunning = true;
     private static Options _options;
-    private static List<Scenario>? _scenarios;
+    private static ObservableCollection<Scenario>? _scenarios;
 
     // If set, holds the scenario the user selected
     private static Scenario? _selectedScenario;
@@ -280,11 +281,12 @@ internal class UICatalogApp
         {
             _topLevelColorScheme = "Base";
 
-            int item = _scenarios!.FindIndex (
-                                              s =>
-                                                  s.GetName ()
-                                                   .Equals (options.Scenario, StringComparison.OrdinalIgnoreCase)
-                                             );
+            int item = _scenarios!.IndexOf (
+                                            _scenarios!.FirstOrDefault (
+                                                                        s =>
+                                                                            s.GetName ()
+                                                                             .Equals (options.Scenario, StringComparison.OrdinalIgnoreCase)
+                                                                       )!);
             _selectedScenario = (Scenario)Activator.CreateInstance (_scenarios [item].GetType ())!;
 
             Application.Init (driverName: _forceDriver);
@@ -492,7 +494,7 @@ internal class UICatalogApp
                 Title = "_Categories",
                 BorderStyle = LineStyle.Single,
                 SuperViewRendersLineCanvas = true,
-                Source = new ListWrapper (_categories)
+                Source = new ListWrapper<string> (_categories)
             };
             CategoryList.OpenSelectedItem += (s, a) => { ScenarioList!.SetFocus (); };
             CategoryList.SelectedItemChanged += CategoryView_SelectedChanged;
@@ -691,17 +693,16 @@ internal class UICatalogApp
         private void CategoryView_SelectedChanged (object? sender, ListViewItemEventArgs? e)
         {
             string item = _categories! [e!.Item];
-            List<Scenario> newlist;
+            ObservableCollection<Scenario> newlist;
 
             if (e.Item == 0)
             {
                 // First category is "All"
                 newlist = _scenarios!;
-                newlist = _scenarios!;
             }
             else
             {
-                newlist = _scenarios!.Where (s => s.GetCategories ().Contains (item)).ToList ();
+                newlist = new (_scenarios!.Where (s => s.GetCategories ().Contains (item)).ToList ());
             }
 
             ScenarioList.Table = new EnumerableTableSource<Scenario> (