簡體   English   中英

“SelectedIndexChanged”在ListBox中的“Items.Clear()”之后沒有觸發

[英]“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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM