- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我正在尝试在 Windows 窗体中的 ListBox 之间拖放多个项目。我遇到的问题是,如果我按住 Shift 键选择多个项目并尝试拖放它而不释放该键,则会出现错误。实际上,SelectedIndices 和 SelectedItems 只显示 1 个项目,即我第一个单击的项目,即使 ListBox 中突出显示了多个项目。
我正在使用 SelectionMode = MultiExtended
void ZListBox_MouseMove(object sender, MouseEventArgs e)
{
if (isDraggingPoint.HasValue && e.Button == MouseButtons.Left && SelectedIndex >= 0)
{
var pointToClient = PointToClient(MousePosition);
if (isDraggingPoint.Value.Y != pointToClient.Y)
{
lastIndexItemOver = -1;
isDraggingPoint = null;
var dropResult = DoDragDrop(SelectedItems, DragDropEffects.Copy);
}
}
}
似乎如果我在执行“DoDragDrop”之前不释放鼠标左键,则不会选择项目,并且如果我尝试从其他列表框中获取 SelectedIndices,则计数是“的数量”选定的项目”,但是当我尝试导航列表时,我收到 IndexOutOfRangeException。
有什么解决办法吗?
重现问题的示例代码:(重现:1- 选择一个项目2-按住 Shift 并单击另一个项目,然后不释放 Shift 和鼠标按钮,拖动该项目(如果“if”内有断点,您将在 SelectedItems 上仅看到 1 个项目))
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
Load += Form1_Load;
}
private void Form1_Load(object sender, EventArgs e)
{
var someList = new List<ListItemsTest>();
someList.Add(new ListItemsTest() { ID = 1, Name = "Name 1" });
someList.Add(new ListItemsTest() { ID = 2, Name = "Name 2" });
someList.Add(new ListItemsTest() { ID = 3, Name = "Name 3" });
someList.Add(new ListItemsTest() { ID = 4, Name = "Name 4" });
someList.Add(new ListItemsTest() { ID = 5, Name = "Name 5" });
listBox1.DisplayMember = "Name";
listBox1.ValueMember = "ID";
listBox1.DataSource = someList;
listBox1.SelectionMode = SelectionMode.MultiExtended;
listBox1.MouseMove += ListBox1_MouseMove;
listBox1.AllowDrop = true;
}
void ListBox1_MouseMove(object sender, MouseEventArgs e)
{
if (e.Button == MouseButtons.Left && listBox1.SelectedIndex >= 0)
{
var dropResult = DoDragDrop(listBox1.SelectedItems, DragDropEffects.Copy);
}
}
public class ListItemsTest
{
public int ID { get; set; }
public string Name { get; set; }
}
}
最佳答案
另一个示例,如果您需要知道在列表框中选择了哪些项目,请使用 SHIFT 键创建扩展选择,即使您不需要启动 Draq&Drop
操作:
使用您在问题中提供的数据样本,即列表。
在示例中,List<int>
( lbSelectedIndexes
) 用于跟踪当前在列表框中选择的项目。仅当使用 SHIFT
执行选择时,才会填充此列表。键,或启动拖放操作后。这对于确定选择的类型很有用。
在所有其他情况下 List<int>
为空且 SelectedItems
和SelectedIndices
集合可用于确定当前选择的项目。
SystemInformation.DragSize值还用于确定在按下左键时移动鼠标指针时是否应启动拖动操作。
当开始拖放操作时,会出现一个新的 DataObject填充了与当前选择相对应的列表框项目,无论选择是如何执行的。
DragDropEffects设置为 DragDropEffects.Copy
。
Point lbMouseDownPosition = Point.Empty;
List<int> lbSelectedIndexes = new List<int>();
private void listBox1_MouseDown(object sender, MouseEventArgs e)
{
var lb = sender as ListBox;
lbMouseDownPosition = e.Location;
lbSelectedIndexes = new List<int>();
int idx = lb.IndexFromPoint(e.Location);
if (ModifierKeys == Keys.Shift && idx != lb.SelectedIndex) {
lbSelectedIndexes.AddRange(Enumerable.Range(
Math.Min(idx, lb.SelectedIndex),
Math.Abs((idx - lb.SelectedIndex)) + 1).ToArray());
}
}
private void listBox1_MouseMove(object sender, MouseEventArgs e)
{
if (e.Button == MouseButtons.Left &&
((Math.Abs(e.X - lbMouseDownPosition.X) > SystemInformation.DragSize.Width) ||
(Math.Abs(e.Y - lbMouseDownPosition.Y) > SystemInformation.DragSize.Height)))
{
var lb = sender as ListBox;
DataObject obj = new DataObject();
if (lbSelectedIndexes.Count == 0) {
lbSelectedIndexes = lb.SelectedIndices.OfType<int>().ToList();
}
List<object> selection = lb.Items.OfType<object>().Where((item, idx) =>
lbSelectedIndexes.IndexOf(idx) >= 0).ToList();
obj.SetData(typeof(IList<ListItemsTest>), selection);
lb.DoDragDrop(obj, DragDropEffects.Copy);
}
}
要测试结果,请将另一个列表框( listBox2
,此处)放在表单上,设置其 AlloDrop
属性至true
并订阅DragEnter
和 DragDrop
事件。
当鼠标指针进入第二个 ListBox 客户区时,DragDropEffects.Copy
如果 e.Data.GetDataPresent() 则触发效果方法检测到拖动的对象包含 List<ListItemsTest>
。
如果数据格式被接受,数据对象将转换回 List<ListItemsTest>
- 使用IDataObject.GetData()方法 - 并设置为 DataSource
的listBox2
.
private void listBox2_DragDrop(object sender, DragEventArgs e)
{
ListBox lb = sender as ListBox;
if (e.Data != null && e.Data.GetDataPresent(typeof(IList<ListItemsTest>))) {
lb.DisplayMember = "Name";
lb.ValueMember = "ID";
lb.DataSource = e.Data.GetData(typeof(IList<ListItemsTest>));
}
}
private void listBox2_DragEnter(object sender, DragEventArgs e)
{
if (e.Data.GetDataPresent(typeof(IList<ListItemsTest>))) {
e.Effect = DragDropEffects.Copy;
}
}
关于c# - ListBox多选拖放问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54430120/
我正在尝试用 Swift 编写这段 JavaScript 代码:k_combinations 到目前为止,我在 Swift 中有这个: import Foundation import Cocoa e
我是一名优秀的程序员,十分优秀!