簡體   English   中英

C# 帶有單選按鈕行為的選中列表框

[英]C# checkedlistbox with radiobutton behavior

最近幾天我一直在尋找解決這個問題的方法,但還沒有找到合適的解決方案。 我制作了一個帶有選中列表框的 WinForm,它必須表現為單選按鈕組。 我知道這不是可取的,但我自己沒有選擇這個。 我正在嘗試擴展我對 WinForm 的了解,所以我抓住了一個程序並嘗試模仿這種行為,所以請留在我身邊。

我想要在我的選中列表框中的單選按鈕屬性:

  • 您只能檢查一項。 (很容易做到,見下面的代碼)
  • 始終檢查一項。 (這是我問題的根源)
  • 當您單擊復選框/項目符號時,它會一鍵檢查,單擊文本不會改變任何內容。 (我也想出了一個)

我需要的 Checkedlistbox 屬性:

  • 復選框后面的可選文本。 (用於重命名和刪除列表中的項目)

我大部分時間都在工作,除非選擇了一個項目而未選中另一個項目。 那時可以取消選中列表中的每個項目。

這是 ItemCheck 事件的代碼。

private string _checkedName = "";
bool _autorizeCheck {get; set;}

private void OnItemCheck(object sender, ItemCheckEventArgs e)
{
            var list = sender as CheckedListBox;

            #region//Click checkbox
            if (!_authorizeCheck)
            {
                e.NewValue = e.CurrentValue;
            }
            #endregion

            #region//Radiobutton config
            if (e.CurrentValue == CheckState.Unchecked)
            {
                for (int i = 0; i < list.Items.Count; i++)
                {
                    if (i != e.Index)
                    {
                        _checkedName = list.Items[e.Index].ToString();
                        list.SetItemChecked(i, false);
                    }
                }
            }
            else if(e.CurrentValue == CheckState.Checked && _checkedName == list.Items[e.Index].ToString())
            {
                if (list.CheckedItems.Count == 1)
                {
                    e.NewValue = e.CurrentValue;
                }
            }
            #endregion
}

這是單擊復選框的代碼:

private void OnMouseDown_checkedListBox(object sender, MouseEventArgs e)
        {
            #region//Check if checkbox is clicked
            var checkedListBox = sender as CheckedListBox;
            var location = checkedListBox.PointToClient(Cursor.Position);
            for (int i = 0; i < checkedListBox.Items.Count; i++)
            {
                var rec = checkedListBox.GetItemRectangle(i);
                rec.Width = 16;

                if (rec.Contains(location))
                {
                    _authorizeCheck = true;
                    bool newValue = !checkedListBox.GetItemChecked(i);
                    checkedListBox.SetItemChecked(i, newValue); 
                    _authorizeCheck = false;

                    return;
                }
            }
            #endregion
        }

制作一個新的 class Form2,將其粘貼到上面:

public partial class Form2 : Form
{
    private int index = 0; //helper to track the selected index
    public Form2()
    {
        InitializeComponent();
        checkedListBox1.SetItemChecked(0, true); //check at least one item
    }

    //this fires before an item is checked. Really, Microsoft should perhaps have called it ItemCheckChanging
    private void checkedListBox1_ItemCheck(object sender, ItemCheckEventArgs e)
    {
        if (index == -1) //programmatic change, exit early; see below
            return;
        else if (index == e.Index)
            e.NewValue = CheckState.Checked; //undo an attempt to uncheck the checked item
        else
        {
            var oldIndex = index; //what item do we want to uncheck
            index = -1; //prevent event handler firing again when we..
            checkedListBox1.SetItemChecked(oldIndex, false); //..uncheck th old
            index = e.Index; //track the newly checked
        }
    }
}

順便說一句,如果您使用綁定到具有 2 列、一個布爾值和一個文本的表的數據網格視圖,您的生活可能會更簡單。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

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