wersja skróconaListBox ScrollIntoView podczas korzystania CollectionViewSource z GroupDescriptions (tj IsGrouping == true)
chciałbym przewinąć element ListBox
polu widzenia, gdy wybór jest zmieniany.
Długa wersja
Mam ListBox
z ItemsSource
związanego z CollectionViewSource
z GroupDescription
, jak na poniższym przykładzie.
<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>
Istnieje zdarzenie SelectionChanged
w pliku z kodem.
public List<Animal> Animals { get; set; }
private void ListBox_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
ListBox control = (ListBox)sender;
control.ScrollIntoView(control.SelectedItem);
}
Teraz. Jeśli ustawię AnimalsListBox.SelectedItem
na element, który obecnie nie jest widoczny, chciałbym, aby był przewinięty w widoku. W tym przypadku robi się to trudne, ponieważjest grupami (właściwość IsGrouped
to true
), a niepowodzenie wywołania ScrollIntoView
.
System.Windows.Controls.ListBox
przez Reflektor. Uwaga: base.IsGrouping
w OnBringItemIntoView
.
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;
}
Pytania
- Może ktoś wyjaśnić, dlaczego to robi nie pracę przy użyciuzgrupowanie?
- Zawsze zwraca zawsze zwraca
null
, mimo że jego stan informuje o wygenerowaniu wszystkich kontenerów.
- Zawsze zwraca zawsze zwraca
- Jak mogę uzyskać przewijanie widoku, gdy przy użyciu grupy?
Powinieneś zmienić swoją odpowiedź na poprawną, a nie powyższą. – Valentein
@ Valentein: Zmieniłem zaznaczoną odpowiedź. JEDNAK, jak porady [crazyarabian] (http://stackoverflow.com/a/7375646/73025) pomogły mi w zdiagnozowaniu problemu, dobrze byłoby oddać głos ** obie ** odpowiedzi, jeśli skorzystasz z mojego ostatecznego rozwiązania. – Dennis
Przy użyciu .NET 4.5.1 i MVVM można użyć zachowania, aby to zrobić. Zachowanie działa w obu scenariuszach, ponieważ jest opóźniony. – Kelly