我有一个以XAML定义的绑定listBox
<ListBox ItemsSource="{Binding Messages}" ItemTemplateSelector="{StaticResource lc_messageTemplateSelector}"
ScrollViewer.HorizontalScrollBarVisibility="Disabled" HorizontalContentAlignment="Stretch"
SelectedItem="{Binding SelectedMessage, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"
IsSynchronizedWithCurrentItem="True" VirtualizingPanel.ScrollUnit="Pixel" Background="White"
ItemContainerStyle="{StaticResource NakedListBoxItem}">
<ListBox.ItemsPanel>
<ItemsPanelTemplate>
<VirtualizingStackPanel VerticalAlignment="Bottom" />
</ItemsPanelTemplate>
</ListBox.ItemsPanel>
<ListBox.Resources>
</ListBox.Resources>
<i:Interaction.Behaviors>
<classes:ScrollIntoViewBehavior />
</i:Interaction.Behaviors>
我确实向web服务发出请求以获取所需的记录并填写Messages - ObservableCollection,所有项目都会根据需要显示,我遇到的问题是,在我加载所有项目后,我需要使其显示最后一个一。 所以我设置它
SelectedMessage = Messages.Last();
默认情况下,这并不能使用数据绑定,所以我创建了(在SO上找到)这个行为
public sealed class ScrollIntoViewBehavior : Behavior<ListBox>
{
protected override void OnAttached()
{
base.OnAttached();
AssociatedObject.SelectionChanged += ScrollIntoView;
}
protected override void OnDetaching()
{
AssociatedObject.SelectionChanged -= ScrollIntoView;
base.OnDetaching();
}
private static void ScrollIntoView(object o, SelectionChangedEventArgs e)
{
Selector selector = o as Selector;
if (selector is ListBox)
{
(selector as ListBox).ScrollIntoView(selector.SelectedItem);
}
}
}
但这不起作用。
这里可能有什么问题以及如何使用数据绑定使其工作。
是否可能是因为某些项目具有复杂的DataTemplate,其中的Image控件以异步模式加载图像并更改ListBox的大小,然后滚动操作错误?
我看到的是,有时它会显示最后一个元素,有时它会滚动到一个随机元素,当它以正确的方式工作时找不到关系。
THX
答案 0 :(得分:0)
<ScollViewer x:Name="scroller">
<ListBox x:Name="listbox" SelectionChanged="selectionChanged"
ScrollViewer.VerticalScrollBarVisibility="Disabled"/>
</ScrollViewer>`
然后你有代码隐藏
private void selectionChanged(object sender, SelectionChangedEventArgs args)
{
var container = listbox.ItemContainerGenerator.ContainerFromIndex(listbox.SelectedIndex) as FrameworkElement;
if (container == null) return;
var transform = container.TransformToVisual(scroller);
var elementLocation = transform.Transform(new Point(0, 0));
double newVerticalOffset = elementLocation.Y + scroller.VerticalOffset;
scroller.ScrollToVerticalOffset(newVerticalOffset);
}