diff --git a/Terminal.Gui/Views/IListDataSource.cs b/Terminal.Gui/Views/IListDataSource.cs
new file mode 100644
index 000000000..981642f0b
--- /dev/null
+++ b/Terminal.Gui/Views/IListDataSource.cs
@@ -0,0 +1,63 @@
+#nullable enable
+using System.Collections;
+using System.Collections.Specialized;
+
+namespace Terminal.Gui;
+
+/// Implement to provide custom rendering for a .
+public interface IListDataSource : IDisposable
+{
+ ///
+ /// Event to raise when an item is added, removed, or moved, or the entire list is refreshed.
+ ///
+ event NotifyCollectionChangedEventHandler CollectionChanged;
+
+ /// Returns the number of elements to display
+ int Count { get; }
+
+ /// Returns the maximum length of elements to display
+ int Length { get; }
+
+ ///
+ /// Allow suspending the event from being invoked,
+ /// if , otherwise is .
+ ///
+ bool SuspendCollectionChangedEvent { get; set; }
+
+ /// Should return whether the specified item is currently marked.
+ /// , if marked, otherwise.
+ /// Item index.
+ bool IsMarked (int item);
+
+ /// This method is invoked to render a specified item, the method should cover the entire provided width.
+ /// The render.
+ /// The list view to render.
+ /// Describes whether the item being rendered is currently selected by the user.
+ /// The index of the item to render, zero for the first item and so on.
+ /// The column where the rendering will start
+ /// The line where the rendering will be done.
+ /// The width that must be filled out.
+ /// The index of the string to be displayed.
+ ///
+ /// The default color will be set before this method is invoked, and will be based on whether the item is selected
+ /// or not.
+ ///
+ void Render (
+ ListView listView,
+ bool selected,
+ int item,
+ int col,
+ int line,
+ int width,
+ int start = 0
+ );
+
+ /// Flags the item as marked.
+ /// Item index.
+ /// If set to value.
+ void SetMark (int item, bool value);
+
+ /// Return the source as IList.
+ ///
+ IList ToList ();
+}
diff --git a/Terminal.Gui/Views/ListView.cs b/Terminal.Gui/Views/ListView.cs
index 4f8b17803..efb6a9e51 100644
--- a/Terminal.Gui/Views/ListView.cs
+++ b/Terminal.Gui/Views/ListView.cs
@@ -1,68 +1,9 @@
using System.Collections;
using System.Collections.ObjectModel;
using System.Collections.Specialized;
-using static Terminal.Gui.SpinnerStyle;
namespace Terminal.Gui;
-/// Implement to provide custom rendering for a .
-public interface IListDataSource : IDisposable
-{
- ///
- /// Event to raise when an item is added, removed, or moved, or the entire list is refreshed.
- ///
- event NotifyCollectionChangedEventHandler CollectionChanged;
-
- /// Returns the number of elements to display
- int Count { get; }
-
- /// Returns the maximum length of elements to display
- int Length { get; }
-
- ///
- /// Allow suspending the event from being invoked,
- /// if , otherwise is .
- ///
- bool SuspendCollectionChangedEvent { get; set; }
-
- /// Should return whether the specified item is currently marked.
- /// , if marked, otherwise.
- /// Item index.
- bool IsMarked (int item);
-
- /// This method is invoked to render a specified item, the method should cover the entire provided width.
- /// The render.
- /// The list view to render.
- /// Describes whether the item being rendered is currently selected by the user.
- /// The index of the item to render, zero for the first item and so on.
- /// The column where the rendering will start
- /// The line where the rendering will be done.
- /// The width that must be filled out.
- /// The index of the string to be displayed.
- ///
- /// The default color will be set before this method is invoked, and will be based on whether the item is selected
- /// or not.
- ///
- void Render (
- ListView listView,
- bool selected,
- int item,
- int col,
- int line,
- int width,
- int start = 0
- );
-
- /// Flags the item as marked.
- /// Item index.
- /// If set to value.
- void SetMark (int item, bool value);
-
- /// Return the source as IList.
- ///
- IList ToList ();
-}
-
///
/// ListView renders a scrollable list of data where each item can be activated to perform an
/// action.
@@ -200,7 +141,7 @@ public class ListView : View, IDesignable
return !SetFocus ();
});
- AddCommand (Command.SelectAll, (ctx) => MarkAll((bool)ctx.KeyBinding?.Context!));
+ AddCommand (Command.SelectAll, (ctx) => MarkAll ((bool)ctx.KeyBinding?.Context!));
// Default keybindings for all ListViews
KeyBindings.Add (Key.CursorUp, Command.Up);
@@ -353,7 +294,7 @@ public class ListView : View, IDesignable
SetContentSize (new Size (_source?.Length ?? Viewport.Width, _source?.Count ?? Viewport.Width));
if (IsInitialized)
{
- // Viewport = Viewport with { Y = 0 };
+ // Viewport = Viewport with { Y = 0 };
}
KeystrokeNavigator.Collection = _source?.ToList ();
@@ -453,11 +394,11 @@ public class ListView : View, IDesignable
/// Ensures the selected item is always visible on the screen.
public void EnsureSelectedItemVisible ()
{
+ // TODO: This check is not needed.
if (SuperView?.IsInitialized == true)
{
- if (_selected < Viewport.Y)
+ if (_selected <= Viewport.Y)
{
- // TODO: The Max check here is not needed because, by default, Viewport enforces staying w/in ContentArea (View.ScrollSettings).
Viewport = Viewport with { Y = _selected };
}
else if (Viewport.Height > 0 && _selected >= Viewport.Y + Viewport.Height)
@@ -485,7 +426,7 @@ public class ListView : View, IDesignable
return Source.IsMarked (SelectedItem);
}
- // BUGBUG: Shouldn't this retrn Source.IsMarked (SelectedItem)
+ // BUGBUG: Shouldn't this return Source.IsMarked (SelectedItem)
return false;
}
@@ -515,7 +456,10 @@ public class ListView : View, IDesignable
if (me.Flags == MouseFlags.WheeledDown)
{
- ScrollVertical (1);
+ if (Viewport.Y + Viewport.Height < GetContentSize ().Height)
+ {
+ ScrollVertical (1);
+ }
return true;
}
@@ -529,7 +473,10 @@ public class ListView : View, IDesignable
if (me.Flags == MouseFlags.WheeledRight)
{
- ScrollHorizontal (1);
+ if (Viewport.X + Viewport.Width < GetContentSize ().Width)
+ {
+ ScrollHorizontal (1);
+ }
return true;
}
@@ -1209,7 +1156,7 @@ public class ListWrapper : IListDataSource, IDisposable
var maxLength = 0;
- for (var i = 0; i < _source.Count; i++)
+ for (var i = 0; i < _source!.Count; i++)
{
object t = _source [i];
int l;
diff --git a/UICatalog/Scenarios/CharacterMap/CharMap.cs b/UICatalog/Scenarios/CharacterMap/CharMap.cs
index 6f4093a36..8b7d283ad 100644
--- a/UICatalog/Scenarios/CharacterMap/CharMap.cs
+++ b/UICatalog/Scenarios/CharacterMap/CharMap.cs
@@ -472,7 +472,10 @@ public class CharMap : View, IDesignable
{
if (mouseEvent.Flags == MouseFlags.WheeledDown)
{
- ScrollVertical (1);
+ if (Viewport.Y + Viewport.Height - HEADER_HEIGHT < GetContentSize ().Height)
+ {
+ ScrollVertical (1);
+ }
return mouseEvent.Handled = true;
}
@@ -484,7 +487,10 @@ public class CharMap : View, IDesignable
if (mouseEvent.Flags == MouseFlags.WheeledRight)
{
- ScrollHorizontal (1);
+ if (Viewport.X + Viewport.Width < GetContentSize ().Width)
+ {
+ ScrollHorizontal (1);
+ }
return mouseEvent.Handled = true;
}
@@ -496,7 +502,7 @@ public class CharMap : View, IDesignable
return false;
}
-
+
private void Handle_MouseClick (object? sender, MouseEventArgs me)
{
if (me.Flags != MouseFlags.ReportMousePosition && me.Flags != MouseFlags.Button1Clicked && me.Flags != MouseFlags.Button1DoubleClicked)