WPF 訊息框 TextBox 系結新資料時讓游標和滾動條跳到最下面
獨立觀察員 2020 年 9 月 3 日
我們在使用 WPF 的 TextBox 作為訊息展示框時,如果想在出現滾動條之后,新訊息到來時還能夠被看到,也就是說讓滾動條始終在最下面,或者說游標始終在最后面,有什么方法呢?
當然,直接在后臺寫邏輯,在附加新訊息時控制滾動潭訓者游標移到最后,這是一個辦法,不過,本文探討的是直接在前臺 Xaml 處實作這個需求,這樣更適合于 MVVM 模式的程式,
需要用到 System.Windows.Interactivity.dll 和 Microsoft.Expression.Interactions.dll 這兩個動態庫:

關于這兩個動態庫,有些人說使用 NuGet 安裝(版本很舊了),有些人說是安了 Blend 之后才有,還有的人從網上搜索下載,事實上,如果你是做開發的,或者是喜歡安各種軟體的朋友,那么很大概率上,在你的電腦的很多隱秘的角落,都散落著它們的身影,所以,我們只需要使用類似 Everything 這樣的軟體進行搜索,就能拿來為我所用了,


至于選擇哪個,則可以看檔案版本,或者明顯更適合你的程式的那個(依據 .NET 版本),我這次選擇的 dll 版本號分別為 3.0.40218 和 2.0.20525:

找到后,將它們拷貝到專案中,并添加參考,然后在 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,將游標位置的值系結為文本長度,這樣就能將游標置于最后了,(這里面應該還能簡化或者改進,大家自行探索)
先來看看動圖效果:

可以看到輸入一個字符后,也就是資訊變動了之后,游標馬上跳到了最后面,所以,這個是訊息框專用的,不適用于輸入框,
最后來看看實戰的效果吧(動圖):

可以看到,效果是能達到,不過要求是文本框要先獲得焦點,這個要求說實話也無可厚非,
如果實在要在未獲取焦點時也能到最底下,可使用 呼叫方法指令(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
祝使用愉快!
同步首發:
http://dlgcy.com/wpf-textbox-scroll-bottom/
微信公眾號
轉載請註明出處,本文鏈接:https://www.uj5u.com/net/1747.html
標籤:WPF
上一篇:WPF實作的加載影片
