如何在 C# (Winform) 中只用鼠标制作多选列表框?
How to make multiselect listbox only with mouse in C# (Winform)?
我有 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));
}
}
}
我该如何解决!?
我想提一下,您使用 SelectionMode.MultiExtended
实现了此功能,但您需要按 CTRL + Click
或 SHIFT + 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];
如何运作?
取 当前索引 并取反 (!
) 该索引处的值。这样你就可以用鼠标获得select/unselect特性。
因为我只使用当前索引,数组中的其他值保持不变我可以对数组中的所有值使用 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]);
}
}
}
ListBox 控件有一个 属性 'SelectionMode'
您可以将其设置为:
- 一个
- 多重简单
- 多扩展
查看此link了解详情
我有 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));
}
}
}
我该如何解决!?
我想提一下,您使用 SelectionMode.MultiExtended
实现了此功能,但您需要按 CTRL + Click
或 SHIFT + 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];
如何运作?
取 当前索引 并取反 (!
) 该索引处的值。这样你就可以用鼠标获得select/unselect特性。
因为我只使用当前索引,数组中的其他值保持不变我可以对数组中的所有值使用 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]);
}
}
}
ListBox 控件有一个 属性 'SelectionMode' 您可以将其设置为:
- 一个
- 多重简单
- 多扩展
查看此link了解详情