Wpf 有没有一种简单的方法可以让ListView自动滚动到最近添加的项目,而无需在代码中编写任何代码?

Wpf 有没有一种简单的方法可以让ListView自动滚动到最近添加的项目,而无需在代码中编写任何代码?,wpf,listview,scroll,Wpf,Listview,Scroll,我有一个绑定到可观察集合的ListView。当项目添加到可观察集合时,listview不会自动滚动以显示最近添加的项目。我试图坚持良好的WPF实践,并且希望避免在视图的代码隐藏中编写任何代码。有没有一种简单的方法可以通过XAML或相应模型的代码来实现这一点 <ListView HorizontalAlignment="Center" ItemsSource="{Binding ScenarioSnippets}" Background="{x:Null}"

我有一个绑定到可观察集合的ListView。当项目添加到可观察集合时,listview不会自动滚动以显示最近添加的项目。我试图坚持良好的WPF实践,并且希望避免在视图的代码隐藏中编写任何代码。有没有一种简单的方法可以通过XAML或相应模型的代码来实现这一点

<ListView HorizontalAlignment="Center" ItemsSource="{Binding ScenarioSnippets}" Background="{x:Null}" 
                      BorderBrush="{x:Null}" BorderThickness="0" SelectionMode="Single" VerticalAlignment="Top" 
                      HorizontalContentAlignment="Center" IsSynchronizedWithCurrentItem="True">
                <ListView.ItemContainerStyle>
                    <Style TargetType="{x:Type ListViewItem}">
                        <Setter Property="Focusable" Value="False" />
                    </Style>
                </ListView.ItemContainerStyle>
                <ListView.View>
                    <GridView Selector.IsSelected="True" AllowsColumnReorder="False">
                        <GridView.Columns>
                            <GridViewColumn CellTemplate="{StaticResource ScenarioSnippetItemCellTemplate}" 
                                            HeaderContainerStyle="{StaticResource GridViewHeaderStyle}" />
                        </GridView.Columns>
                    </GridView>
                </ListView.View>
        </ListView>

您需要创建一个允许您的
列表视图
尊重您最终追求的MVVM范式


可以找到带有
列表框的解决方案/示例(对于
列表视图
,可以轻松修改)。

您可以使用混合行为:

public class AutoScrollToLastItemBehavior : Behavior<ListBox>
{
    protected override void OnAttached()
    {
        base.OnAttached();
        var collection = AssociatedObject.Items.SourceCollection as INotifyCollectionChanged;
        if (collection != null)
            collection.CollectionChanged += collection_CollectionChanged;
    }

    protected override void OnDetaching()
    {
        base.OnDetaching();
        var collection = AssociatedObject.Items.SourceCollection as INotifyCollectionChanged;
        if (collection != null)
            collection.CollectionChanged -= collection_CollectionChanged;
    }

    private void collection_CollectionChanged(object sender, NotifyCollectionChangedEventArgs e)
    {
        if (e.Action == NotifyCollectionChangedAction.Add)
        {
            ScrollToLastItem();
        }
    }

    private void ScrollToLastItem()
    {
        int count = AssociatedObject.Items.Count;
        if (count > 0)
        {
            var last = AssociatedObject.Items[count - 1];
            AssociatedObject.ScrollIntoView(last);
        }
    }
}
公共类AutoScrollToLastItemBehavior:行为
{
受保护的覆盖无效附加()
{
base.onatached();
var collection=AssociatedObject.Items.SourceCollection作为INotifyCollectionChanged;
if(集合!=null)
collection.CollectionChanged+=collection\u CollectionChanged;
}
附加时受保护的覆盖无效()
{
base.OnDetaching();
var collection=AssociatedObject.Items.SourceCollection作为INotifyCollectionChanged;
if(集合!=null)
collection.CollectionChanged-=collection\u CollectionChanged;
}
私有无效集合\u集合已更改(对象发送方,NotifyCollectionChangedEventArgs e)
{
if(e.Action==NotifyCollectionChangedAction.Add)
{
ScrollToLastItem();
}
}
私有无效ScrollToLastItem()
{
int count=AssociatedObject.Items.count;
如果(计数>0)
{
var last=AssociatedObject.Items[计数-1];
AssociatedObject.ScrollIntoView(最后一个);
}
}
}
XAML:



(可以在Blend SDK中的
System.Windows.Interactivity.dll
中找到
行为
交互
类)

我知道使用
ListView.ScrollIntoView()的唯一解决方案
查看仅XAML的解决方案会很有趣
<ListView ItemsSource="...">
    <i:Interaction.Behaviors>
        <local:AutoScrollToLastItemBehavior />
    </i:Interaction.Behaviors>
</ListView>