アップデート:
問題を明確に説明するデモをアップロードしました。こちらからダウンロードしてください。
ListBoxの選択を処理するマネージャークラスを開発しています。(ListBoxが提供するデフォルトの選択機能では、要件を満たすことができません)
したがって、アイテムがリストボックスに追加されると、マネージャークラスは対応するリストボックスアイテムを取得し、それを選択または非選択にする必要があります。
新しく追加されたアイテムのいくつかの情報を伝える必要があると思いますが、 (異なるパラメーターで)複数回呼び出されItemContainerGenerator.ItemsChanged
たときに同じイベント引数を提供するためListBox.Items.Add
、非常に混乱します。新しく追加されたアイテムに対して新しく生成された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では、2つのアイテムがlistBoxに追加され、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;
}
}
}