ListBox ScrollIntoView ao usar CollectionViewSource com GroupDescriptions (ou seja, IsGrouping == True)

Versão curt

Gostaria de rolar oListBox item em exibição quando a seleção é alterad

Versão long

Eu tenho umListBox com oItemsSource ligado a umCollectionViewSource com umGroupDescription, conforme o exemplo abaix

<Window.Resources>
    <CollectionViewSource x:Key="AnimalsView" Source="{Binding Source={StaticResource Animals}, Path=AnimalList}">
        <CollectionViewSource.GroupDescriptions>
            <PropertyGroupDescription PropertyName="Category"/>
        </CollectionViewSource.GroupDescriptions>
    </CollectionViewSource>  
</Window.Resources>

<ListBox x:Name="AnimalsListBox"ItemsSource="{Binding Source={StaticResource AnimalsView}}" ItemTemplate="{StaticResource AnimalTemplate}" SelectionChanged="ListBox_SelectionChanged">
    <ListBox.GroupStyle>
        <GroupStyle HeaderTemplate="{StaticResource CategoryTemplate}" />
    </ListBox.GroupStyle>
</ListBox>

Existe umSelectionChanged no arquivo a code-behin

public List<Animal> Animals { get; set; }

private void ListBox_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
    ListBox control = (ListBox)sender;
    control.ScrollIntoView(control.SelectedItem);
}

Agora. Se eu definir oAnimalsListBox.SelectedItem para um item que não está visível no momento, gostaria que ele fosse exibido. É aqui que fica complicado, pois oListBox está sendo grupos (oIsGrouped propriedade étrue) a chamada paraScrollIntoView falha.

System.Windows.Controls.ListBox através daRefleto. Note obase.IsGrouping noOnBringItemIntoView.

public void ScrollIntoView(object item)
{
    if (base.ItemContainerGenerator.Status == GeneratorStatus.ContainersGenerated)
    {
        this.OnBringItemIntoView(item);
    }
    else
    {
        base.Dispatcher.BeginInvoke(DispatcherPriority.Loaded, new DispatcherOperationCallback(this.OnBringItemIntoView), item);
    }
}

private object OnBringItemIntoView(object arg)
{
    FrameworkElement element = base.ItemContainerGenerator.ContainerFromItem(arg) as FrameworkElement;
    if (element != null)
    {
        element.BringIntoView();
    }
    else if (!base.IsGrouping && base.Items.Contains(arg))
    {
        VirtualizingPanel itemsHost = base.ItemsHost as VirtualizingPanel;
        if (itemsHost != null)
        {
            itemsHost.BringIndexIntoView(base.Items.IndexOf(arg));
        }
    }
    return null;
}

Questõe

Alguém pode explicar por que ele faz trabalhar quando usando agrupamento?OItemContainerGenerator.ContainerFromItem sempre retornanull, mesmo que seu status indique que todos os contêineres foram geradoComo posso visualizar a rolagem quando usando agrupamento?

questionAnswers(2)

yourAnswerToTheQuestion