2
0
Эх сурвалжийг харах

Merge pull request #3500 from BDisp/v1_2897-listwrapper-source-workaround

v1 Fixes #2897. ListView ListWrapper - marking does work if you give an IList which in which the count changes
Tig 1 жил өмнө
parent
commit
5a2b844e7b

+ 31 - 5
Terminal.Gui/Views/ListView.cs

@@ -601,10 +601,12 @@ namespace Terminal.Gui {
 		/// <returns></returns>
 		public virtual bool MoveEnd ()
 		{
-			if (source.Count > 0 && selected != source.Count - 1) {
+			if (source?.Count > 0 && selected != source.Count - 1) {
 				selected = source.Count - 1;
 				if (top + selected > Frame.Height - 1) {
-					top = selected;
+					top = selected < Frame.Height - 1
+						? Math.Max (Frame.Height - selected + 1, 0)
+						: Math.Max (selected - Frame.Height + 1, 0);
 				}
 				OnSelectedChanged ();
 				SetNeedsDisplay ();
@@ -749,6 +751,11 @@ namespace Terminal.Gui {
 		public void EnsureSelectedItemVisible ()
 		{
 			SuperView?.LayoutSubviews ();
+			// If last item is selected and is removed, ensures a valid selected item
+			if (Source != null && selected > Source.Count - 1) {
+				SelectedItem = Source.Count - 1;
+				SetNeedsDisplay ();
+			}
 			if (selected < top) {
 				top = selected;
 			} else if (Frame.Height > 0 && selected >= top + Frame.Height) {
@@ -831,11 +838,30 @@ namespace Terminal.Gui {
 		}
 
 		/// <inheritdoc/>
-		public int Count => src != null ? src.Count : 0;
+		public int Count {
+			get {
+				CheckAndResizeMarksIfRequired ();
+				return src?.Count ?? 0;
+			}
+		}
 
 		/// <inheritdoc/>
 		public int Length => len;
 
+		void CheckAndResizeMarksIfRequired ()
+		{
+			if (src != null && count != src.Count) {
+				count = src.Count;
+				BitArray newMarks = new BitArray (count);
+				for (var i = 0; i < Math.Min (marks.Length, newMarks.Length); i++) {
+					newMarks [i] = marks [i];
+				}
+				marks = newMarks;
+
+				len = GetMaxLengthItem ();
+			}
+		}
+
 		int GetMaxLengthItem ()
 		{
 			if (src == null || src?.Count == 0) {
@@ -896,7 +922,7 @@ namespace Terminal.Gui {
 		/// <inheritdoc/>
 		public bool IsMarked (int item)
 		{
-			if (item >= 0 && item < count)
+			if (item >= 0 && item < Count)
 				return marks [item];
 			return false;
 		}
@@ -904,7 +930,7 @@ namespace Terminal.Gui {
 		/// <inheritdoc/>
 		public void SetMark (int item, bool value)
 		{
-			if (item >= 0 && item < count)
+			if (item >= 0 && item < Count)
 				marks [item] = value;
 		}
 

+ 9 - 9
UnitTests/Views/ListViewTests.cs

@@ -300,16 +300,16 @@ namespace Terminal.Gui.ViewTests {
 			Assert.Equal (19, lv.SelectedItem);
 			TestHelpers.AssertDriverContentsWithFrameAre (@"
 ┌──────────┐
+│Line10    │
+│Line11    │
+│Line12    │
+│Line13    │
+│Line14    │
+│Line15    │
+│Line16    │
+│Line17    │
+│Line18    │
 │Line19    │
-│          │
-│          │
-│          │
-│          │
-│          │
-│          │
-│          │
-│          │
-│          │
 └──────────┘", output);
 
 			Assert.True (lv.ScrollUp (20));