更新:
我上传了一个演示,试图清楚地解释我的问题。在这里下载。
我正在开发一个处理列表框选择的管理器类。(ListBox提供的默认选择功能不能满足我的要求)
因此,当一个项目添加到 ListBox 时,我的管理器类应该获取相应的 ListBoxItem并使其被选中或取消选中。
虽然我认为ItemContainerGenerator.ItemsChanged
应该告诉新添加的项目的一些信息,但它在ListBox.Items.Add
多次调用时提供相同的事件arg(使用不同的参数),这让我很困惑。谁能告诉我如何为新添加的项目获取新生成的 ListBoxItem。
演示问题的代码:
<Window x:Class="WpfApplication2.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:System="clr-namespace:System;assembly=mscorlib"
Title="MainWindow" Height="350" Width="525">
<StackPanel>
<Button Content="Add two items" Click="Button_Click_1"/>
<ListBox Name="listBox">
<System:Int32>1</System:Int32>
<System:Int32>2</System:Int32>
<System:Int32>3</System:Int32>
</ListBox>
</StackPanel>
</Window>
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
SelectionManager selectionManager = new SelectionManager();
selectionManager.Join(listBox);
}
private void Button_Click_1(object sender, RoutedEventArgs e)
{
listBox.Items.Add(4);
listBox.Items.Add(5);
}
}
这里,在Button_Click 中,listBox 添加了两个item,selectionManager 应该同时获取ListBoxItem。
class SelectionManager
{
public void Join(ListBox element)
{
element.ItemContainerGenerator.ItemsChanged += ItemContainerGenerator_ItemsChanged;
}
private List<int> listBoxItemPendingJoinIndexes = new List<int>();
void ItemContainerGenerator_StatusChanged(object sender, EventArgs e)
{
Contract.Requires(listBoxItemPendingJoinIndexes.Count > 0);
ItemContainerGenerator generator = (ItemContainerGenerator)sender;
if (generator.Status != GeneratorStatus.ContainersGenerated)
return;
generator.StatusChanged -= ItemContainerGenerator_StatusChanged;
foreach (var index in listBoxItemPendingJoinIndexes)
{
ListBoxItem listBoxItem = (ListBoxItem)generator.ContainerFromIndex(index);
Join(listBoxItem);
}
listBoxItemPendingJoinIndexes.Clear();
}
void ItemContainerGenerator_ItemsChanged(object sender, ItemsChangedEventArgs e)
{
ItemContainerGenerator generator = (ItemContainerGenerator)sender;
switch (e.Action)
{
case NotifyCollectionChangedAction.Add:
listBoxItemPendingJoinIndexes.Add(e.Position.Index
+ e.Position.Offset);//same e.Position
generator.StatusChanged += ItemContainerGenerator_StatusChanged;
break;
}
}
}