【问题标题】:How to make multiselect listbox only with mouse in C# (Winform)?如何在 C#(Winform)中仅使用鼠标制作多选列表框?
【发布时间】:2015-03-26 11:03:09
【问题描述】:

我有 listbox 里面有一些东西,我在找这个:

总是以前的项目保持选中状态,如果我点击一个未选中的项目它也被选中但如果它已经被选中它没有被选中。 我使用了这些代码,但效果不佳! 这是我的代码(这个根本不起作用):

public partial class Options_Form : Form
{
    public Options_Form()
    {
        InitializeComponent();
    }

    private void Options_Load(object sender, EventArgs e)
    {
        AceMP_Class cl = new AceMP_Class();
        listBox1.Items.AddRange(cl.SupportedFiles_stringarray());
        listBox1.SelectionMode = SelectionMode.MultiExtended;
        listBox1.Size = listBox1.PreferredSize;
        listboxitemsState_array = new bool[cl.SupportedFiles_stringarray().Length];
    }

    private void button2_Click(object sender, EventArgs e)
    {
        listBox1.ClearSelected();
        //selecteditemsindex_list.Clear();
    }

    //List<int> selecteditemsindex_list = new List<int>();

    bool[] listboxitemsState_array;

    private void listBox1_MouseDown(object sender, MouseEventArgs e)
    {
        for (int i = 0; i < listboxitemsState_array.Length; i++)
        {
            if (listboxitemsState_array[i])
            {
                listBox1.SetSelected(i, true);
            }
            else
            {
                listBox1.SetSelected(i, false);
            }
        }

        //if (listBox1.GetSelected(listBox1.IndexFromPoint(e.X, e.Y)))
        if (listboxitemsState_array[listBox1.IndexFromPoint(e.X, e.Y)])
        {
            listBox1.SetSelected(listBox1.IndexFromPoint(e.X, e.Y), false);
            listboxitemsState_array[listBox1.IndexFromPoint(e.X, e.Y)] = false;
        }
        else
        {
            listBox1.SetSelected(listBox1.IndexFromPoint(e.X, e.Y), true);
            listboxitemsState_array[listBox1.IndexFromPoint(e.X, e.Y)] = true;
        }

    }

    private void listBox1_MouseUp(object sender, MouseEventArgs e)
    {

        for (int i = 0; i < listboxitemsState_array.Length; i++)
        {
            if (listboxitemsState_array[i])
            {
                listBox1.SetSelected(i, true);
            }
            else
            {
                listBox1.SetSelected(i, false);
            }
        }

        //if (listBox1.GetSelected(listBox1.IndexFromPoint(e.X, e.Y)))
        if (listboxitemsState_array[listBox1.IndexFromPoint(e.X, e.Y)])
        {
            listBox1.SetSelected(listBox1.IndexFromPoint(e.X, e.Y), false);
            listboxitemsState_array[listBox1.IndexFromPoint(e.X, e.Y)] = false;
        }
        else
        {
            listBox1.SetSelected(listBox1.IndexFromPoint(e.X, e.Y), true);
            listboxitemsState_array[listBox1.IndexFromPoint(e.X, e.Y)] = true;
        }

    }

}

但这个工作但不是很好!

public partial class Options_Form : Form
{
    public Options_Form()
    {
        InitializeComponent();
    }

    private void Options_Load(object sender, EventArgs e)
    {
        AceMP_Class cl = new AceMP_Class();
        listBox1.Items.AddRange(cl.SupportedFiles_stringarray());
        listBox1.SelectionMode = SelectionMode.MultiExtended;
        listBox1.Size = listBox1.PreferredSize;
    }

    private void button2_Click(object sender, EventArgs e)
    {
        listBox1.ClearSelected();
        selecteditemsindex_list.Clear();
    }

    List<int> selecteditemsindex_list = new List<int>();

    private void listBox1_Click(object sender, EventArgs e)
    {
        listBox1.ClearSelected();
    }

    private void listBox1_MouseDown(object sender, MouseEventArgs e)
    {
        for (int i = 0; i < selecteditemsindex_list.Count; i++)
        {
            listBox1.SetSelected(selecteditemsindex_list[i], true);
        }
    }

    private void listBox1_MouseUp(object sender, MouseEventArgs e)
    {

        for (int i = 0; i < selecteditemsindex_list.Count; i++)
        {
            listBox1.SetSelected(selecteditemsindex_list[i], true);
        }
        if (listBox1.GetSelected(listBox1.IndexFromPoint(e.X, e.Y)))
        {
            listBox1.SetSelected(listBox1.IndexFromPoint(e.X, e.Y), false);
        }
        else
        {
            listBox1.SetSelected(listBox1.IndexFromPoint(e.X, e.Y), true);
            selecteditemsindex_list.Add(listBox1.IndexFromPoint(e.X, e.Y));
        }
    }

}

我该如何解决这个问题!?

【问题讨论】:

    标签: c# select listbox


    【解决方案1】:

    我想提一下,您使用SelectionMode.MultiExtended 实现了此功能,但您需要按CTRL + ClickSHIFT + Click

    要做到这一点只能用鼠标

    1) 当我与@ACE(他提出使用virtualkey 的想法)讨论时,一个更好的解决方案出现在您点击时press CTRL key。在MouseDown 上按CTRL,在MouseUp 上释放CTRL 键。

    public partial class Options_Form : Form
    {
        public Options_Form()
        {
            InitializeComponent();
        }
    
        private void Options_Load(object sender, EventArgs e)
        {
            AceMP_Class cl = new AceMP_Class();
            listBox1.Items.AddRange(cl.SupportedFiles_stringarray());
            listBox1.SelectionMode = SelectionMode.MultiSimple;
            listBox1.Size = listBox1.PreferredSize;
        }
    
        [DllImport("user32.dll", SetLastError = true)]
        static extern void keybd_event(byte bVk, byte bScan, int dwFlags, int dwExtraInfo);
    
        public const uint KEYEVENTF_KEYUP = 0x02;
        public const uint VK_CONTROL = 0x11;
    
        private void listBox1_MouseDown(object sender, MouseEventArgs e)
        {
            keybd_event(Convert.ToByte(VK_CONTROL), 0, 0, 0);
        }
    
        private void listBox1_MouseUp(object sender, MouseEventArgs e)
        {
            keybd_event(Convert.ToByte(VK_CONTROL), 0, Convert.ToByte(KEYEVENTF_KEYUP), 0);
        }
    }
    

    2) 我想到的最简单的解决方案(如果你快速按下点击会有一些缺点)是在 MouseClick 事件上使用并有一个 bool 数组该数组中的每个index 都会告诉我是否被选中。

    selecteditemsindex_list[selectedIndex] = !selecteditemsindex_list[selectedIndex];
    

    它是如何工作的?

    获取 当前索引 并取反 (!) 该索引处的值。这样您就可以使用鼠标获得选择/取消选择功能。

    因为我只使用 当前索引 数组中的 其他值 保持未修改,我可以将 SetSelected 用于所有值大批。这样你就可以用鼠标多选了。

    public partial class Options_Form : Form
    {
        public Options_Form()
        {
            InitializeComponent();
        }
        bool[] selecteditemsindex_list;
    
        private void Options_Load(object sender, EventArgs e)
        {
            AceMP_Class cl = new AceMP_Class();
            listBox1.Items.AddRange(cl.SupportedFiles_stringarray());
            listBox1.SelectionMode = SelectionMode.MultiExtended;
            listBox1.Size = listBox1.PreferredSize;
            selecteditemsindex_list = new bool[listBox1.Items.Count];
        }
    
        private void listBox1_MouseDown(object sender, MouseEventArgs e)
        {
            var selectedIndex = listBox1.SelectedIndex;
            selecteditemsindex_list[selectedIndex] = !selecteditemsindex_list[selectedIndex];
            for (int i = 0; i < selecteditemsindex_list.Count(); i++)
            {
                listBox1.SetSelected(i, selecteditemsindex_list[i]);
            }
        }
    }
    

    【讨论】:

    • 感谢您的回答 :) 我会尝试并通知您
    • 你知道为什么有人拒绝我的问题吗!?
    • 选择第二个项目时出错 :( 对于这一行:selecteditemsindex_list[selectedIndex] = !selecteditemsindex_list[selectedIndex]; 错误:索引超出了数组的范围。
    • &是啊其实我想做的就是Ctrl键操作,但是不按住ctrl键直接点击!
    • 是的,它已经初始化了!我认为这会有所帮助:listBox1.SelectedIndex -1 int selectedIndex -1 int 这些是发生错误时的值
    【解决方案2】:

    ListBox 控件有一个属性“SelectionMode” 您可以将其设置为:

    1. 一个
    2. 多重简单
    3. 多扩展

    详情请见link

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2023-04-04
      • 1970-01-01
      • 2020-06-07
      • 1970-01-01
      • 2016-05-07
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多