【发布时间】:2011-09-09 20:14:27
【问题描述】:
短版
我想在选择更改时滚动ListBox 项目到视图中。
加长版
我有一个 ListBox 和 ItemsSource 绑定到 CollectionViewSource 和 GroupDescription,如下例所示。
<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>
代码隐藏文件中有一个SelectionChanged 事件。
public List<Animal> Animals { get; set; }
private void ListBox_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
ListBox control = (ListBox)sender;
control.ScrollIntoView(control.SelectedItem);
}
现在。如果我将AnimalsListBox.SelectedItem 设置为当前不可见的项目,我想让它在视图中滚动。这就是它变得棘手的地方,因为ListBox 是组(IsGrouped 属性是true)对ScrollIntoView 的调用失败。
System.Windows.Controls.ListBox 通过反射器。注意OnBringItemIntoView 中的base.IsGrouping。
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;
}
问题
- 谁能解释为什么它在使用分组时不起作用?
-
ItemContainerGenerator.ContainerFromItem始终返回null,即使它的状态表明所有容器都已生成。
-
- 使用分组时如何实现滚动到视图?
【问题讨论】: