C# 在按住Shift键单击时调用多次; ///它第一次触发Shift单击的项目时已选中,下一次触发时 ///激发时,按住Shift键并单击所需的其余项目将被选中。因此,使用 ///存储选择状态的SelectedValueChanged处理程序将在以下情况下失败 ///情景: ///i)用户最多可选择2项 ///ii)用户单击Line1 ///iii)选择的值已更改,但未超过最大值,选择已存储 ///我们称之为Selection_A,它包含第1行 ///iii)用户按下Shift键,并从称为Line3的第一个选项向下移动项目2行 ///iv)SelectedValueChanged激发,该选项显示只有第1行和第3行被激活 ///已选择,因此未超过最大值,选择存储让我们调用它 ///包含第1行、第3行的选项 ///v)SelectedValueChanged会再次触发,此时会选择第1行、第2行和第3行, ///因此,已超过最大值,因此我们将恢复到先前存储的选择 ///这就是选择B,我们想要的是恢复到选择A ///b)MousedDown事件在第一个SelectedValueChanged事件之后触发,因此保存 ///MouseDown中的状态也会在错误的时间存储状态。 私有无效值stbox\u MouseUp(对象发送方,MouseEventArgs e) { if(this.MaxSelection==null) { 返回; } ListBox ListBox=发送方作为ListBox; //存储当前选择 此.previousSelection.Clear(); foreach(列表框中的int-selectedIndex.selectedIndes) { this.previousSelection.Add(selectedIndex); } }
我认为这是一种简单的方法,在本例中,限制为6项C# 在按住Shift键单击时调用多次; ///它第一次触发Shift单击的项目时已选中,下一次触发时 ///激发时,按住Shift键并单击所需的其余项目将被选中。因此,使用 ///存储选择状态的SelectedValueChanged处理程序将在以下情况下失败 ///情景: ///i)用户最多可选择2项 ///ii)用户单击Line1 ///iii)选择的值已更改,但未超过最大值,选择已存储 ///我们称之为Selection_A,它包含第1行 ///iii)用户按下Shift键,并从称为Line3的第一个选项向下移动项目2行 ///iv)SelectedValueChanged激发,该选项显示只有第1行和第3行被激活 ///已选择,因此未超过最大值,选择存储让我们调用它 ///包含第1行、第3行的选项 ///v)SelectedValueChanged会再次触发,此时会选择第1行、第2行和第3行, ///因此,已超过最大值,因此我们将恢复到先前存储的选择 ///这就是选择B,我们想要的是恢复到选择A ///b)MousedDown事件在第一个SelectedValueChanged事件之后触发,因此保存 ///MouseDown中的状态也会在错误的时间存储状态。 私有无效值stbox\u MouseUp(对象发送方,MouseEventArgs e) { if(this.MaxSelection==null) { 返回; } ListBox ListBox=发送方作为ListBox; //存储当前选择 此.previousSelection.Clear(); foreach(列表框中的int-selectedIndex.selectedIndes) { this.previousSelection.Add(selectedIndex); } },c#,listbox,multi-select,C#,Listbox,Multi Select,我认为这是一种简单的方法,在本例中,限制为6项 string[] lbitems; private void listBox1_SelectedIndexChanged(object sender, EventArgs e) { ListBox listBox = (ListBox)sender; if (listBox.SelectedItems.Count == 7) { for (int i = 0; i < listBox.SelectedI
string[] lbitems;
private void listBox1_SelectedIndexChanged(object sender, EventArgs e)
{
ListBox listBox = (ListBox)sender;
if (listBox.SelectedItems.Count == 7)
{
for (int i = 0; i < listBox.SelectedItems.Count; i++)
{
bool trovato = false;
for (int j = 0; j < lbitems.Length; j++)
{
if (listBox.SelectedItems[i] == lbitems[j])
{
trovato = true;
break;
}
}
if (trovato == false)
{
listBox.SelectedItems.Remove(listBox.SelectedItems[i]);
break;
}
}
}
else
{
lbitems = new string[listBox.SelectedItems.Count];
listBox.SelectedItems.CopyTo(lbitems, 0);
}
}
string[]lbitems;
私有无效列表框1\u SelectedIndexChanged(对象发送方,事件参数e)
{
ListBox ListBox=(ListBox)发送方;
如果(listBox.SelectedItems.Count==7)
{
对于(int i=0;i
不幸的是,我发现MousedDown和KeyDown在SelectedValueChanged事件后启动。不过,您已经使用MouseUp设计了一个解决方案,我将在稍后发布。非常感谢。我没有测试它,而是假设他们应该被解雇之前。很抱歉,很高兴听到你找到了解决办法。但是,在“最坏”的情况下,只需创建从ListBox继承的自己的控件,并通过重写WndProc方法将其挂接到windows消息处理中。
/// <summary>
/// Handle the ListBox's SelectedValueChanged event, revert the selection if there are too many selected
/// </summary>
/// <param name="sender">the sending object</param>
/// <param name="e">the event args</param>
void ChildSelectionChanged(object sender, EventArgs e)
{
ListBox listBox = sender as ListBox;
//If the number of selected items is greater than the number the user is allowed to select
if ((this.MaxSelection != null) && (listBox.SelectedItems.Count > this.MaxSelection))
{
//Prevent this method from running while reverting the selection
listBox.SelectedIndexChanged -= ChildSelectionChanged;
//Revert the selection to the previously stored selection
try
{
for (int index = 0; index < listBox.Items.Count; index++)
{
if (listBox.SelectedIndices.Contains(index) && !this.previousSelection.Contains(index))
{
listBox.SetSelected(index, false);
}
}
}
catch (ArgumentOutOfRangeException ex)
{
}
catch (InvalidOperationException ex)
{
}
finally
{
//Re-enable this method as an event handler for the selection change event
listBox.SelectedIndexChanged += ChildSelectionChanged;
}
}
else
{
RaiseSelectionChangedEvent();
}
}
/// <summary>
/// Handle the ListBox's MouseUp event, store the selection state.
/// </summary>
/// <param name="sender">the sending object</param>
/// <param name="e">the event args</param>
/// <remarks>This method saves the state of selection of the list box into a class member.
/// This is used by the SelectedValueChanged handler such that when the user selects more
/// items than they are allowed to, it will revert the selection to the state saved here
/// in this MouseUp handler, which is the state of the selection at the end of the previous
/// mouse click.
/// We have to use the MouseUp event since:
/// a) the SelectedValueChanged event is called multiple times when a Shift-click is made;
/// the first time it fires the item that was Shift-clicked is selected, the next time it
/// fires, the rest of the items intended by the Shift-click are selected. Thus using the
/// SelectedValueChanged handler to store the selection state would fail in the following
/// scenario:
/// i) the user is allowed to select 2 items max
/// ii) the user clicks Line1
/// iii) the SelectedValueChanged fires, the max has not been exceeded, selection stored
/// let's call it Selection_A which contains Line1
/// iii) the user Shift-clicks and item 2 lines down from the first selection called Line3
/// iv) the SelectedValueChanged fires, the selection shows that only Line1 and Line3 are
/// selected, hence the max has not been exceeded, selection stored let's call it
/// Selection_B which contains Line1, Line3
/// v) the SelectedValueChanged fires again, this time Line1, Line2, and Line3 are selected,
/// hence the max has been exceeded so we revert to the previously stored selection
/// which is Selection_B, what we wanted was to revert to Selection_A
/// b) the MouseDown event fires after the first SelectedValueChanged event, hence saving the
/// state in MouseDown also stores the state at the wrong time.</remarks>
private void valuesListBox_MouseUp(object sender, MouseEventArgs e)
{
if (this.MaxSelection == null)
{
return;
}
ListBox listBox = sender as ListBox;
//Store the current selection
this.previousSelection.Clear();
foreach (int selectedIndex in listBox.SelectedIndices)
{
this.previousSelection.Add(selectedIndex);
}
}
string[] lbitems;
private void listBox1_SelectedIndexChanged(object sender, EventArgs e)
{
ListBox listBox = (ListBox)sender;
if (listBox.SelectedItems.Count == 7)
{
for (int i = 0; i < listBox.SelectedItems.Count; i++)
{
bool trovato = false;
for (int j = 0; j < lbitems.Length; j++)
{
if (listBox.SelectedItems[i] == lbitems[j])
{
trovato = true;
break;
}
}
if (trovato == false)
{
listBox.SelectedItems.Remove(listBox.SelectedItems[i]);
break;
}
}
}
else
{
lbitems = new string[listBox.SelectedItems.Count];
listBox.SelectedItems.CopyTo(lbitems, 0);
}
}