phiên bản ngắnListBox ScrollIntoView khi sử dụng CollectionViewSource với GroupDescriptions (ví dụ: IsGrouping == True)
Tôi muốn di chuyển các ListBox
mục vào xem khi lựa chọn được thay đổi.
dài phiên bản
Tôi có một ListBox
với ItemsSource
ràng buộc với một CollectionViewSource
với một GroupDescription
, theo ví dụ dưới đây.
<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>
Có sự kiện SelectionChanged
trong tệp sau mã.
public List<Animal> Animals { get; set; }
private void ListBox_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
ListBox control = (ListBox)sender;
control.ScrollIntoView(control.SelectedItem);
}
Hiện tại. Nếu tôi đặt AnimalsListBox.SelectedItem
thành một mục hiện không hiển thị, tôi muốn nó cuộn trong chế độ xem. Đây là nơi nó trở nên phức tạp, vì ListBox
là các nhóm (thuộc tính IsGrouped
là true
) cuộc gọi đến ScrollIntoView
không thành công.
System.Windows.Controls.ListBox
qua Phản xạ. Lưu ý base.IsGrouping
trong số 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;
}
Câu hỏi
- bất cứ ai có thể giải thích lý do tại sao nó không làm việc khi sử dụng nhóm?
ItemContainerGenerator.ContainerFromItem
luôn trả vềnull
, mặc dù trạng thái của nó cho biết tất cả các vùng chứa đã được tạo.
- Làm cách nào để có thể cuộn cuộn vào chế độ xem khi sử dụng nhóm?
Bạn nên thay đổi câu trả lời cho đúng câu trả lời, chứ không phải câu trả lời ở trên. – Valentein
@Valentein: Tôi đã thay đổi câu trả lời đã đánh dấu. TUYÊN BỐ như [crazyarabian] (http://stackoverflow.com/a/7375646/73025) lời khuyên đã giúp tôi trong việc chẩn đoán vấn đề nó sẽ tốt lên bỏ phiếu ** cả hai ** câu trả lời nếu bạn sử dụng giải pháp cuối cùng của tôi. – Dennis
Sử dụng .NET 4.5.1 và MVVM bạn có thể sử dụng một hành vi để thực hiện việc này. Các hành vi hoạt động trong cả hai kịch bản khi nó cháy muộn. – Kelly