ComboBox cursonDownKey nullref fix (#1472)

* added null guard to fix null ref when pressing keyDown inside combobox
Improved an error message when view cannot be found

* Added a unit test to ensure combobox can process all key events
Found and fixed a new nullref

* Found a new bug when source is already present and combobox is added to a top view

* searchSet is auto initialized to new List() now to make the code a little bit safer
This commit is contained in:
Igor Bagdamyan
2021-09-30 00:14:32 +03:00
committed by GitHub
parent 8bfa2f0425
commit f602d3bd1d
3 changed files with 43 additions and 23 deletions

View File

@@ -1870,16 +1870,19 @@ namespace Terminal.Gui {
}
}
if (edges.Any () && edges.First ().From != Application.Top) {
if (!ReferenceEquals (edges.First ().From, edges.First ().To)) {
throw new InvalidOperationException ($"TopologicalSort (for Pos/Dim) cannot find {edges.First ().From}. Did you forget to add it to {this}?");
} else {
throw new InvalidOperationException ("TopologicalSort encountered a recursive cycle in the relative Pos/Dim in the views of " + this);
}
} else {
// return L (a topologically sorted order)
return result;
}
if (edges.Any ()) {
var (from, to) = edges.First ();
if (from != Application.Top) {
if (!ReferenceEquals (from, to)) {
throw new InvalidOperationException ($"TopologicalSort (for Pos/Dim) cannot find {from} linked with {to}. Did you forget to add it to {this}?");
} else {
throw new InvalidOperationException ("TopologicalSort encountered a recursive cycle in the relative Pos/Dim in the views of " + this);
}
}
}
// return L (a topologically sorted order)
return result;
}
/// <summary>

View File

@@ -64,7 +64,7 @@ namespace Terminal.Gui {
/// </summary>
public event Action<ListViewItemEventArgs> OpenSelectedItem;
IList searchset;
readonly IList searchset = new List<object> ();
ustring text = "";
readonly TextField search;
readonly ListView listview;
@@ -314,7 +314,7 @@ namespace Terminal.Gui {
}
if (e.Key == Key.CursorDown && search.HasFocus) { // jump to list
if (searchset.Count > 0) {
if (searchset?.Count > 0) {
listview.TabStop = true;
listview.SetFocus ();
SetValue (searchset [listview.SelectedItem]);
@@ -329,7 +329,7 @@ namespace Terminal.Gui {
return true;
}
if (e.Key == Key.CursorUp && listview.HasFocus && listview.SelectedItem == 0 && searchset.Count > 0) // jump back to search
if (e.Key == Key.CursorUp && listview.HasFocus && listview.SelectedItem == 0 && searchset?.Count > 0) // jump back to search
{
search.CursorPosition = search.Text.RuneCount;
search.SetFocus ();
@@ -406,7 +406,7 @@ namespace Terminal.Gui {
{
isShow = false;
listview.TabStop = false;
if (listview.Source.Count == 0 || searchset.Count == 0) {
if (listview.Source.Count == 0 || (searchset?.Count ?? 0) == 0) {
text = "";
return;
}
@@ -452,11 +452,7 @@ namespace Terminal.Gui {
private void ResetSearchSet (bool noCopy = false)
{
if (searchset == null) {
searchset = new List<object> ();
} else {
searchset.Clear ();
}
searchset.Clear ();
if (autoHide || noCopy)
return;
@@ -465,9 +461,6 @@ namespace Terminal.Gui {
private void SetSearchSet ()
{
if (searchset == null) {
searchset = new List<object> ();
}
// force deep copy
foreach (var item in Source.ToList ()) {
searchset.Add (item);
@@ -503,7 +496,7 @@ namespace Terminal.Gui {
/// Consider making public
private void ShowList ()
{
listview.SetSource (searchset);
listview.SetSource (searchset);
listview.Clear (); // Ensure list shrinks in Dialog as you type
listview.Height = CalculatetHeight ();
this.SuperView?.BringSubviewToFront (this);

View File

@@ -0,0 +1,24 @@
using System;
using System.Linq;
using Terminal.Gui;
using Xunit;
namespace UnitTests {
public class ComboBoxTests {
[Fact]
[AutoInitShutdown]
public void EnsureKeyEventsDoNotCauseExceptions ()
{
var comboBox = new ComboBox ("0");
var source = Enumerable.Range (0, 15).Select (x => x.ToString ()).ToArray ();
comboBox.SetSource(source);
Application.Top.Add(comboBox);
foreach (var key in (Key [])Enum.GetValues (typeof(Key))) {
comboBox.ProcessKey (new KeyEvent (key, new KeyModifiers ()));
}
}
}
}