WPF

    科技2025-01-31  38

    WPF_Behavior之自动滚动到底部的ListBox

    一、前言

    有一个ListBox,它的ItemSource绑定了一个集合,当这个集合动态增加的时候,ListBox的Item也会增多。问题来了,由于ListBox控件的高度有限,如果其Item过多,那么ListBox的垂直滑轮不会自动滚动到最新添加的Item,如果有什么办法让它自动滚动就好。

    其实有一个办法就是添加触发器,这个方法应该可以实现的,但是触发器只能对某一个控件添加,触发器的效果也只能对该控件起作用,如果有其它类似的控件也需要该效果,那么不得不在其他类似控件上也添加该触发器。

    Behavior是一类控件的共同特征,在WPF中通过Behavior可以封装一些通用的界面控件效果和功能,从而实现代码重用来提高开发效率。

    二、Behavior简介

    1、引用dll

    可直接在NuGet中搜索Interactivity,找到System.Windows.Interactivityl.WPF下载安装即可。使用到的其实是名叫System.Windows.Interactivity.dll的库。

    但是安装后还有一个库:Microsoft.Expression.Interactions,这个库里提供了一些已经定义好的Behavior,例如:MouseDragElementBehavior等。参考文档: https://docs.microsoft.com/zh-cn/previous-versions/visualstudio/design-tools/expression-studio-4/ff726476(v=expression.40)

    2、继承自Behavior : Behavior where T : DependencyObject

    自定一个类,这个类继承Behavior,其中T为控件类型,或其父类类型。这里我们尽量要使用父类类型,这样所有的子类就可以使用该Behavior了。

    3、通过AssociatedObject关联对象

    这个对象指我们的T类型的控件。AssociatedObject是一个T类型的只读属性。

    4、重写Behavior里面的两个函数OnAOnttached与OnDetaching

    这里的两个方法都是相对控件来说的。一般在OnAOnttached方法中订阅控件的某个或者几个事件,在这个事件中我们可以添加我们想要的行为或者效果。一般在OnDetaching方法中我们会注销这个事件的订阅。

    5、使用

    1)添加命名空间,例:

    xmlns:i="http://schemas.microsoft.com/expression/2010/interactivity"

    2)使用,在对应控件中添加Behavior特性,例:

    <textBlock <i:Interaction.Behaviors> <local:LightedEffectBehavior/> </i:Interaction.Behaviors> </TextBlock>

    三、ListBoxScrollToBottomBehavior的实现

    直接上代码

    public class ListBoxScrollToBottomBehavior:Behavior<ListBox> { protected override void OnAttached() { base.OnAttached(); //只有ICollectionView类型才有CollectionChanged事件 //所以这里强转了一下类型 ((ICollectionView)AssociatedObject.Items).CollectionChanged += ListBoxScrollToBottomBehavior_CollectionChanged; } private void ListBoxScrollToBottomBehavior_CollectionChanged(object sender, System.Collections.Specialized.NotifyCollectionChangedEventArgs e) { //这里正好使用了ListBox的ScrollIntoView()方法,也只有ListBox类型才有这个方法 //其父类没有这里方法,所以T使用的ListBox,没有使用其父类 if (AssociatedObject.HasItems) AssociatedObject.ScrollIntoView(AssociatedObject.Items[AssociatedObject.Items.Count - 1]); } protected override void OnDetaching() { base.OnDetaching(); ((ICollectionView)AssociatedObject.Items).CollectionChanged -= ListBoxScrollToBottomBehavior_CollectionChanged; } } xmlns:i="http://schemas.microsoft.com/expression/2010/interactivity" xmlns:ei="http://schemas.microsoft.com/expression/2010/interactions" <ListBox ItemsSource="{Binding list}" Grid.Row="0"> <i:Interaction.Behaviors> <local:ListBoxScrollToBottomBehavior/> <ei:MouseDragElementBehavior/> </i:Interaction.Behaviors> <ListBox.ItemTemplate> <DataTemplate> <TextBlock Text="{Binding .}" HorizontalAlignment="Center"/> </DataTemplate> </ListBox.ItemTemplate> </ListBox>

    四、效果

    Processed: 0.016, SQL: 8