对于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方法的任何想法吗? 它是否需要隐藏/覆盖其他方法,还是有办法避免这种情况?
答案 0 :(得分:5)
查看Reflector中的代码,Items上的Clear()方法只会重置.Net对象的内部对象列表(并且没有,如您所知,触发OnSelectedIndexChanged)。
SelectedIndex属性返回-1,因为属性的getter中的逻辑指示如果内部列表中没有项目,则应返回-1。
答案 1 :(得分:2)
Clear()仅清除控件的内部集合。 Clear()不会触发SelectedIndexChanged事件,因为只有通过更改CurrentlySelectedIndex才会引发该事件。尝试使用lst。ClearSelected()代替。调用此方法相当于将SelectedIndex属性设置为负一(-1)。您可以使用此方法快速取消选择列表中的所有项目。或者,您可以尝试调用Items.Clear()并通过调用ListBox来跟随它。RefreshItems
答案 2 :(得分:1)
可能是一个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();
也许这可以解决你的问题。
答案 3 :(得分:0)
这是我的方式,它与现有代码兼容。
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;
}
}
}