WPF 消息框 TextBox 绑定新数据时让光标和滚动条跳到最下面

WPF 消息框 TextBox 绑定新数据时让光标和滚动条跳到最下面

WPF 消息框 TextBox 绑定新数据时让光标滚动条跳到最下面

独立观察员 2020 年 9 月 3 日

 

我们在使用 WPF 的 TextBox 作为消息展示框时,如果想在出现滚动条之后,新消息到来时还能够被看到,也就是说让滚动条始终在最下面,或者说光标始终在最后面,有什么方法呢?

当然,直接在后台写逻辑,在附加新消息时控制滚动条或者光标移到最后,这是一个办法。不过,本文探讨的是直接在前台 Xaml 处实现这个需求,这样更适合于 MVVM 模式的程序。

 

需要用到 System.Windows.Interactivity.dll 和 Microsoft.Expression.Interactions.dll 这两个动态库:

%title插图%num

 

关于这两个动态库,有些人说使用 NuGet 安装(版本很旧了),有些人说是安了 Blend 之后才有,还有的人从网上搜索下载。事实上,如果你是做开发的,或者是喜欢安各种软件的朋友,那么很大概率上,在你的电脑的很多隐秘的角落,都散落着它们的身影。所以,我们只需要使用类似 Everything 这样的软件进行搜索,就能拿来为我所用了。

%title插图%num

%title插图%num

 

至于选择哪个,则可以看文件版本,或者明显更适合你的程序的那个(依据 .NET 版本)。我这次选择的 dll 版本号分别为 3.0.40218 和 2.0.20525:

%title插图%num

 

找到后,将它们拷贝到项目中,并添加引用。然后在 Xaml 中添加命名空间引用:

xmlns:i="clr-namespace:System.Windows.Interactivity;assembly=System.Windows.Interactivity"
xmlns:ei="http://schemas.microsoft.com/expression/2010/interactions"

 

这样就可以在 TextBox 中使用了:

<!--消息框-->
<TextBox x:Name="TBInfo" Grid.Column="0" Height="Auto" TextWrapping="Wrap" AcceptsReturn="True" VerticalScrollBarVisibility="Auto" Text="{Binding Info}">
    <i:Interaction.Triggers>
        <ei:DataTrigger Binding="{Binding Text.Length, ElementName=TBInfo}" Comparison="NotEqual" Value="0">
            <ei:ChangePropertyAction TargetName="TBInfo" PropertyName="CaretIndex" 
                Value="{Binding ElementName=TBInfo, Path=Text.Length}">
            </ei:ChangePropertyAction>
        </ei:DataTrigger>
    </i:Interaction.Triggers>
</TextBox>

 

<i:Interaction.Triggers> 就是触发器开始,ei:DataTrigger 就是数据触发器(注意区别于 WPF 自带的 DataTrigger),绑定了元素 TBInfo 的 Text.Length,当其值不等 0 时执行内部指令。ei:ChangePropertyAction 指令表示改变属性值,目标元素也是 TBInfo,属性为插入位置,也就是光标位置 CaretIndex,将光标位置的值绑定为文本长度,这样就能将光标置于最后了。(这里面应该还能简化或者改进,大家自行探索)

 

先来看看动图效果:

%title插图%num

 

可以看到输入一个字符后,也就是信息变动了之后,光标马上跳到了最后面。所以,这个是消息框专用的,不适用于输入框。

 

最后来看看实战的效果吧(动图):

%title插图%num

 

可以看到,效果是能达到,不过要求是文本框要先获得焦点,这个要求说实话也无可厚非。

 

如果实在要在未获取焦点时也能到最底下,可使用 调用方法指令(ei:CallMethodAction) 控制滚动条滚动到最后:

<ei:CallMethodAction MethodName="ScrollToEnd"></ei:CallMethodAction>

 

这句的后台等价代码为:

TBInfo.ScrollToEnd();

 

建议两个指令一起使用,所以最终消息框代码为:

<TextBox x:Name="TBInfo" Grid.Column="0" Height="Auto" TextWrapping="Wrap" VerticalScrollBarVisibility="Auto" Text="{Binding Info}">
    <i:Interaction.Triggers>
        <ei:DataTrigger Binding="{Binding Text.Length, ElementName=TBInfo}" Comparison="NotEqual" Value="0">
            <ei:ChangePropertyAction TargetName="TBInfo" PropertyName="CaretIndex" 
                Value="{Binding ElementName=TBInfo, Path=Text.Length}">
            </ei:ChangePropertyAction>
            <ei:CallMethodAction MethodName="ScrollToEnd"></ei:CallMethodAction>
        </ei:DataTrigger>
    </i:Interaction.Triggers>
</TextBox>

 

代码放在了本人的 WPF 模板项目中:https://gitee.com/dlgcy/WPFTemplate 

 

祝使用愉快!

 

原创文章,转载请注明: 转载自 独立观察员(dlgcy.com)

本文链接地址: [WPF 消息框 TextBox 绑定新数据时让光标和滚动条跳到最下面](https://dlgcy.com/wpf-textbox-scroll-bottom/)

关注微信公众号 独立观察员博客(DLGCY_BLOG) 第一时间获取最新文章

%title插图%num

目前为止有一条评论

独立观察员 发布于13:34 - 2022年8月21日

现在一般用 Microsoft.Xaml.Behaviors.Wpf 包来代替那两个动态库。

发表评论