Tengo un ListBox que hasta hace poco mostraba una lista plana de elementos. Pude usar myList.ItemContainerGenerator.ConainerFromItem (thing) para recuperar el "elemento" hosting de ListBoxItem en la lista.¿Cómo funciona ItemContainerGenerator.ContainerFromItem con una lista agrupada?
Esta semana modifiqué ligeramente el ListBox porque CollectionViewSource al que se une para sus elementos tiene habilitada la agrupación. Ahora los elementos dentro de ListBox están agrupados debajo de buenos encabezados.
Sin embargo, desde hacer esto, ItemContainerGenerator.ContainerFromItem ha dejado de funcionar, devuelve nulo incluso para los elementos que sé que están en el ListBox. Heck: ContainerFromIndex (0) devuelve null incluso cuando ListBox está lleno de muchos elementos.
¿Cómo recupero un ListBoxItem de un ListBox que muestra elementos agrupados?
Editar: Aquí está el XAML y el código subyacente para un ejemplo recortado. Esto genera una NullReferenceException porque ContainerFromIndex (1) devuelve null aunque hay cuatro elementos en la lista.
XAML:
<Window x:Class="WpfApplication1.Window1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:scm="clr-namespace:System.ComponentModel;assembly=WindowsBase"
Title="Window1">
<Window.Resources>
<XmlDataProvider x:Key="myTasks" XPath="Tasks/Task">
<x:XData>
<Tasks xmlns="">
<Task Name="Groceries" Type="Home"/>
<Task Name="Cleaning" Type="Home"/>
<Task Name="Coding" Type="Work"/>
<Task Name="Meetings" Type="Work"/>
</Tasks>
</x:XData>
</XmlDataProvider>
<CollectionViewSource x:Key="mySortedTasks" Source="{StaticResource myTasks}">
<CollectionViewSource.SortDescriptions>
<scm:SortDescription PropertyName="@Type" />
<scm:SortDescription PropertyName="@Name" />
</CollectionViewSource.SortDescriptions>
<CollectionViewSource.GroupDescriptions>
<PropertyGroupDescription PropertyName="@Type" />
</CollectionViewSource.GroupDescriptions>
</CollectionViewSource>
</Window.Resources>
<ListBox
x:Name="listBox1"
ItemsSource="{Binding Source={StaticResource mySortedTasks}}"
DisplayMemberPath="@Name"
>
<ListBox.GroupStyle>
<GroupStyle>
<GroupStyle.HeaderTemplate>
<DataTemplate>
<TextBlock Text="{Binding Name}"/>
</DataTemplate>
</GroupStyle.HeaderTemplate>
</GroupStyle>
</ListBox.GroupStyle>
</ListBox>
</Window>
CS:
public Window1()
{
InitializeComponent();
listBox1.ItemContainerGenerator.StatusChanged += ItemContainerGenerator_StatusChanged;
}
void ItemContainerGenerator_StatusChanged(object sender, EventArgs e)
{
if (listBox1.ItemContainerGenerator.Status == System.Windows.Controls.Primitives.GeneratorStatus.ContainersGenerated)
{
listBox1.ItemContainerGenerator.StatusChanged -= ItemContainerGenerator_StatusChanged;
var i = listBox1.ItemContainerGenerator.ContainerFromIndex(1) as ListBoxItem;
// select and keyboard-focus the second item
i.IsSelected = true;
i.Focus();
}
}
¿Qué haces con el contenedor? ¿Se puede explicar lo que hizo el código anterior que realmente funcionó? Hay algunas formas de obtener el contenedor ... ¿Depende de lo que quieras hacer con él? – rudigrobler