浏览代码

Fixes #2545. ListView throw exception if click on the top border. (#2547)

BDisp 2 年之前
父节点
当前提交
c1de5e0dc6
共有 2 个文件被更改,包括 70 次插入2 次删除
  1. 5 2
      Terminal.Gui/Views/ListView.cs
  2. 65 0
      UnitTests/Views/ListViewTests.cs

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

@@ -794,11 +794,14 @@ namespace Terminal.Gui {
 				return true;
 			}
 
-			if (me.Y + top - GetFramesThickness ().Top >= source.Count) {
+			var framesThickness = GetFramesThickness ();
+			if (me.Y + top - framesThickness.Top >= source.Count
+				|| me.Y + top - framesThickness.Top < 0
+				|| me.Y + top > top + Frame.Height - (framesThickness.Top + framesThickness.Bottom)) {
 				return true;
 			}
 
-			selected = top - GetFramesThickness().Top + me.Y;
+			selected = top - GetFramesThickness ().Top + me.Y;
 			if (AllowsAll ()) {
 				Source.SetMark (SelectedItem, !Source.IsMarked (SelectedItem));
 				SetNeedsDisplay ();

+ 65 - 0
UnitTests/Views/ListViewTests.cs

@@ -541,5 +541,70 @@ Item 6", output);
 			var exception = Record.Exception (lv.SetFocus);
 			Assert.Null (exception);
 		}
+
+		[Fact, AutoInitShutdown]
+		public void Clicking_On_Border_Is_Ignored ()
+		{
+			var selected = "";
+			var lv = new ListView {
+				Height = 5,
+				Width = 7,
+				BorderStyle = LineStyle.Single
+			};
+			lv.SetSource (new List<string> { "One", "Two", "Three", "Four" });
+			lv.SelectedItemChanged += (s, e) => selected = e.Value.ToString ();
+			Application.Top.Add (lv);
+			Application.Begin (Application.Top);
+
+			Assert.Equal (new Thickness (1), lv.Border.Thickness);
+			Assert.Equal (-1, lv.SelectedItem);
+			Assert.Equal ("", lv.Text);
+			TestHelpers.AssertDriverContentsWithFrameAre (@"
+┌─────┐
+│One  │
+│Two  │
+│Three│
+└─────┘", output);
+
+			Assert.True (lv.MouseEvent (new MouseEvent {
+				X = 0,
+				Y = 0,
+				Flags = MouseFlags.Button1Clicked
+			}));
+			Assert.Equal ("", selected);
+			Assert.Equal (-1, lv.SelectedItem);
+
+			Assert.True (lv.MouseEvent (new MouseEvent {
+				X = 0,
+				Y = 1,
+				Flags = MouseFlags.Button1Clicked
+			}));
+			Assert.Equal ("One", selected);
+			Assert.Equal (0, lv.SelectedItem);
+
+			Assert.True (lv.MouseEvent (new MouseEvent {
+				X = 0,
+				Y = 2,
+				Flags = MouseFlags.Button1Clicked
+			}));
+			Assert.Equal ("Two", selected);
+			Assert.Equal (1, lv.SelectedItem);
+
+			Assert.True (lv.MouseEvent (new MouseEvent {
+				X = 0,
+				Y = 3,
+				Flags = MouseFlags.Button1Clicked
+			}));
+			Assert.Equal ("Three", selected);
+			Assert.Equal (2, lv.SelectedItem);
+
+			Assert.True (lv.MouseEvent (new MouseEvent {
+				X = 0,
+				Y = 4,
+				Flags = MouseFlags.Button1Clicked
+			}));
+			Assert.Equal ("Three", selected);
+			Assert.Equal (2, lv.SelectedItem);
+		}
 	}
 }