Fixes #1584 - ComboBox is hiding elements below from being clicked/focused (#1585)

* Fixes #1584

* Fixes https://github.com/migueldeicaza/gui.cs/issues/1584#issuecomment-1027987475

* Fixes some bugs with SelectedItem.

* Ensures updating the ComboBox text on leaving the control.

Co-authored-by: BDisp <bd.bdisp@gmail.com>
This commit is contained in:
Thomas Nind
2022-02-06 22:44:33 +00:00
committed by GitHub
parent 24bdaad9d7
commit 3e7d2ef570
3 changed files with 116 additions and 9 deletions

View File

@@ -31,6 +31,8 @@ namespace Terminal.Gui {
// Only need to refresh list if its been added to a container view
if (SuperView != null && SuperView.Subviews.Contains (this)) {
SelectedItem = -1;
search.Text = "";
Search_Changed ("");
SetNeedsDisplay ();
}
@@ -64,7 +66,7 @@ namespace Terminal.Gui {
/// </summary>
public event Action<ListViewItemEventArgs> OpenSelectedItem;
readonly IList searchset = new List<object> ();
readonly IList searchset = new List<object> ();
ustring text = "";
readonly TextField search;
readonly ListView listview;
@@ -156,13 +158,29 @@ namespace Terminal.Gui {
};
}
private bool isShow = false;
private int selectedItem = -1;
/// <summary>
/// Gets the index of the currently selected item in the <see cref="Source"/>
/// </summary>
/// <value>The selected item or -1 none selected.</value>
public int SelectedItem { private set; get; }
public int SelectedItem {
get => selectedItem;
set {
if (selectedItem != value && (value == -1
|| (source != null && value > -1 && value < source.Count))) {
bool isShow = false;
selectedItem = value;
if (selectedItem != -1) {
SetValue (source.ToList () [selectedItem].ToString (), true);
} else {
SetValue ("", true);
}
OnSelectedChanged ();
}
}
}
///<inheritdoc/>
public new ColorScheme ColorScheme {
@@ -244,6 +262,11 @@ namespace Terminal.Gui {
///<inheritdoc/>
public override bool OnLeave (View view)
{
if (source?.Count > 0 && selectedItem > -1 && selectedItem < source.Count - 1
&& text != source.ToList () [selectedItem].ToString ()) {
SetValue (source.ToList () [selectedItem].ToString ());
}
if (autoHide && isShow && view != this && view != search && view != listview) {
isShow = false;
HideList ();
@@ -392,22 +415,26 @@ namespace Terminal.Gui {
}
}
private void SetValue (object text)
private void SetValue (object text, bool isFromSelectedItem = false)
{
search.TextChanged -= Search_Changed;
this.text = search.Text = text.ToString ();
search.CursorPosition = 0;
search.TextChanged += Search_Changed;
SelectedItem = GetSelectedItemFromSource (this.text);
OnSelectedChanged ();
if (!isFromSelectedItem) {
selectedItem = GetSelectedItemFromSource (this.text);
OnSelectedChanged ();
}
}
private void Selected ()
{
isShow = false;
listview.TabStop = false;
if (listview.Source.Count == 0 || (searchset?.Count ?? 0) == 0) {
text = "";
HideList ();
return;
}
@@ -416,6 +443,7 @@ namespace Terminal.Gui {
Search_Changed (search.Text);
OnOpenSelectedItem ();
Reset (keepSearchText: true);
HideList ();
}
private int GetSelectedItemFromSource (ustring value)
@@ -452,7 +480,7 @@ namespace Terminal.Gui {
private void ResetSearchSet (bool noCopy = false)
{
searchset.Clear ();
searchset.Clear ();
if (autoHide || noCopy)
return;
@@ -496,7 +524,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);
@@ -513,6 +541,7 @@ namespace Terminal.Gui {
Reset (SelectedItem > -1);
listview.Clear (rect);
listview.TabStop = false;
SuperView?.SendSubviewToBack (this);
SuperView?.SetNeedsDisplay (rect);
}

View File

@@ -0,0 +1,78 @@
using System.Collections.Generic;
using Terminal.Gui;
namespace UICatalog.Scenarios {
[ScenarioMetadata (Name: "ComboBoxIteration", Description: "ComboBox iteration.")]
[ScenarioCategory ("Controls")]
public class ComboBoxIteration : Scenario {
public override void Setup ()
{
var items = new List<string> () { "one", "two", "three" };
var lbListView = new Label () {
AutoSize = false,
Width = 10,
Height = 1
};
Win.Add (lbListView);
var listview = new ListView (items) {
Y = Pos.Bottom (lbListView) + 1,
Width = 10,
Height = Dim.Fill (2)
};
Win.Add (listview);
var lbComboBox = new Label () {
ColorScheme = Colors.TopLevel,
X = Pos.Right (lbListView) + 1,
Width = Dim.Percent (40)
};
var comboBox = new ComboBox () {
X = Pos.Right (listview) + 1,
Y = Pos.Bottom (lbListView) + 1,
Height = Dim.Fill (2),
Width = Dim.Percent (40)
};
comboBox.SetSource (items);
listview.SelectedItemChanged += (e) => {
lbListView.Text = items [e.Item];
comboBox.SelectedItem = e.Item;
};
comboBox.SelectedItemChanged += (ListViewItemEventArgs text) => {
if (text.Item != -1) {
lbComboBox.Text = text.Value.ToString ();
listview.SelectedItem = text.Item;
}
};
Win.Add (lbComboBox, comboBox);
Win.Add (new TextField { X = Pos.Right (listview) + 1, Y = Pos.Top (comboBox) + 3, Height = 1, Width = 20 });
var btnTwo = new Button ("Two") {
X = Pos.Right (comboBox) + 1,
};
btnTwo.Clicked += () => {
items = new List<string> () { "one", "two" };
comboBox.SetSource (items);
listview.SetSource (items);
listview.SelectedItem = 0;
};
Win.Add (btnTwo);
var btnThree = new Button ("Three") {
X = Pos.Right (comboBox) + 1,
Y = Pos.Top (comboBox)
};
btnThree.Clicked += () => {
items = new List<string> () { "one", "two", "three" };
comboBox.SetSource (items);
listview.SetSource (items);
listview.SelectedItem = 0;
};
Win.Add (btnThree);
}
}
}

View File

@@ -80,7 +80,7 @@ namespace UICatalog.Scenarios {
};
comboBox.SetSource (items);
comboBox.SelectedItemChanged += (ListViewItemEventArgs text) => lbComboBox.Text = items[comboBox.SelectedItem];
comboBox.SelectedItemChanged += (ListViewItemEventArgs text) => lbComboBox.Text = text.Value.ToString ();
Win.Add (lbComboBox, comboBox);
var scrollBarCbx = new ScrollBarView (comboBox.Subviews [1], true);