[英]Unable to get SelectedIndex value after Items.Clear in ListBox
[英]“SelectedIndexChanged” not firing after “Items.Clear()” in ListBox
對於ListBox(選擇模式設置為One),我希望跟蹤是否選擇了所選項目。 為此,我訂閱了一個方法到SelectedIndexChanged並檢查SelectedIndex是否為-1。 但是,我注意到在調用Items.Clear()之后事件不會觸發,即使SelectedIndex更改為-1(如果它還不是-1)。
為什么不開火? 我知道我可以通過在清除列表之前為SelectedIndex分配-1來解決這個問題。 但有更好的方法嗎?
這是一個復制它的簡單代碼:
using System;
using System.Windows.Forms;
namespace ns
{
class Program
{
static ListBox lst = new ListBox();
public static void Main()
{
lst.SelectedIndexChanged += new EventHandler(lst_SelectedIndexChanged);
lst.Items.Add(1);
Console.WriteLine("Setting selected index to 0...");
lst.SelectedIndex = 0; //event fire here
Console.WriteLine("(Selected Index == {0})", lst.SelectedIndex);
Console.WriteLine("Clearing all items...");
lst.Items.Clear(); //event *should* fire here?!
//proof that the selected index has changed
Console.WriteLine("(Selected Index == {0})", lst.SelectedIndex);
}
static void lst_SelectedIndexChanged(object sender, EventArgs e)
{
Console.WriteLine("[!] Selected Index Changed:{0}", lst.SelectedIndex);
}
}
}
編輯:我正在考慮通過創建一個繼承自ListBox的類或通過創建用戶控件來創建自定義列表。 但是我不知道如何處理這個問題。 有關使用inheritance / userControl隱藏/覆蓋clear方法的任何想法嗎? 是否需要隱藏/覆蓋其他方法,還是有辦法避免這種情況?
查看Reflector中的代碼,Items上的Clear()方法只重置.Net對象的內部對象列表(並且沒有,正如您所注意到的那樣,觸發OnSelectedIndexChanged)。
SelectedIndex屬性返回-1,因為屬性的getter中的邏輯指示如果內部列表中沒有項目,則應返回-1。
Clear()僅清除控件的內部集合。 Clear()不會觸發SelectedIndexChanged事件,因為只有通過更改CurrentlySelectedIndex才會引發該事件。 嘗試使用lst。 而是ClearSelected ()。 調用此方法相當於將SelectedIndex屬性設置為負一(-1)。 您可以使用此方法快速取消選擇列表中的所有項目。 或者,您可以嘗試調用Items.Clear()並通過調用ListBox來跟隨它。 RefreshItems
可能是一個hackish解決方案,但這是我想到的:
class myListBox
{
public ListBox myList;
public myListBox()
{
myList = new ListBox();
}
public void listClear()
{
if (myList.Items.Count > 0)
{
myList.SelectedIndex = 0;
}
myList.Items.Clear();
}
}
你可以在主表單中這樣稱呼它:
myListBox example = new myListBox();
example.myList.Items.Add("Example");
example.myList.SelectedIndexChanged += new EventHandler(lst_SelectedIndexChanged);
this.Controls.Add(example.myList);
example.listClear();
也許這可以解決你的問題。
這是我的方式,它與現有代碼兼容。
public class DetailsListView : ListView
{
public new class ListViewItemCollection : ListView.ListViewItemCollection
{
private DetailsListView m_owner;
public ListViewItemCollection(DetailsListView owner)
: base(owner)
{
m_owner = owner;
}
public override void Clear()
{
base.Clear();
m_owner.FireChanged();
}
}
private void FireChanged()
{
base.OnSelectedIndexChanged(EventArgs.Empty);
}
private ListViewItemCollection m_Items;
public DetailsListView()
{
m_Items = new ListViewItemCollection(this);
View = View.Details;
GridLines = true;
HideSelection = false;
FullRowSelect = true;
}
public new ListViewItemCollection Items
{
get
{
return m_Items;
}
}
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.