2011-06-08 28 views
2

我有一个行为奇怪的数据绑定列表框。列表框的SelectionMode属性设置为MultiExtended,并在按钮单击时,我需要将项目复制到另一个控件,在这种情况下,一个TreeView。但是,由于某种原因,我试过的每个迭代器只循环一次。我试过SelectedItemsSelectedIndices。代码摘录:迭代ListBox中的SelectedItems只返回第一项

var movedItems = new List<ListBoxUnderlyingObject>(); 
foreach (var selectedItem in listBox.SelectedItems) 
{ 
    var castItem = selectedItem as ListBoxUnderlyingObject; 
    var newNode = new TreeNode(castItem.SomeString); 
    newNode.Name = castItem.AnotherString; 
    newNode.Tag = castItem; 
    newNode.ForeColor = Color.RoyalBlue; 
    //parentNode was set earlier 
    parentNode.Nodes.Add(newNode); 
    movedItems.Add(selectedItem); 
} 
//use movedItems to remove items from listBox's underlying databound object and rebind 

无论选择了多少项目,循环只执行一次。与SelectedIndices相同。如果我用一个编号的迭代器尝试它,它会失败,出现“索引超出数组范围”错误。

for(var i = 0;i < listBox.SelectedItems.Count;i++) 
{ 
    var castItem = listBox.SelectedItems[i] as ListBoxUnderlyingObject; 
    //etc., the previous line bombs on the second iteration 
} 

如果我之前或循环期间抛出一个Debug.WriteLine(listBox.SelectedItems.Count),它处处体现了正确的计数。我知道这可能是愚蠢的,但我很难过。帮帮我!

跟进

我创建了一个单独的WinForms项目,它模拟的行为几乎完全和SelectedItems工作。我完全困惑。现在,我要尝试在原始项目中添加一个新表单,并查看是否可以在那里重新创建行为。

+0

这是完整的代码?你是使用'DataSource'绑定还是只添加项目到ListBox?是否删除循环内的项目?投射项目并将其添加到列表不应该是任何问题的唯一原因。 – 2011-06-08 18:50:45

+0

添加了treeview代码。它使用数据源进行绑定。不,它不会在循环完成之后删除项目。 – 2011-06-08 20:03:57

+0

在调试器下 - 如果计数是5,它是否允许您检查并查看listBox.SelectedItems [0-4]? – 2011-06-08 20:10:47

回答

0

那么,事实证明我扣留一些关键信息。列表框已启用拖放行为,其中的一部分是MouseDown事件的处理程序。该处理器拥有这些代码是:

private void listBox_MouseDown(object sender, MouseEventArgs e) 
{ 
    if (listBox.Items.Count = 0) return; 
    listBox.DoDragDrop(listBox.SelectedItem, DragDropEffects.Move); 
} 

如果我评论此处理了,SelectedItems正确的行为。现在我必须弄清楚如何正确执行拖放操作,但这是一个不同的问题。

0

查看示例listed on MSDN。他们建议您迭代每个列表项并使用GetSelected Method来确定是否选择了给定的索引,而不是使用选定的项目/项目/索引/索引。

+0

这个例子与这种情况无关。在这种情况下,ListBox通过DataSource属性馈送,因此无法迭代项目集合并使用GetSelected选择项目。 – 2013-01-09 13:36:13

0

我遇到了同样的问题,它让我走到了疯狂的边缘。我没有解释,但我有一个解决方法:设置ListBox的DisplayMember属性。它“应该”使用ToString()方法,但由于某种原因它不起作用,所以我实现了一个属性,该属性返回ToString的值并将DisplayMember映射到该属性。祝你好运。