WPF實(shí)現(xiàn)ScrollViewer滾動(dòng)到指定控件處
在前端 UI 開發(fā)中,有時(shí),我們會(huì)遇到這樣的需求:在一個(gè) ScrollViewer 中有很多內(nèi)容,而我們需要實(shí)現(xiàn)在執(zhí)行某個(gè)操作后能夠定位到其中指定的控件處;這很像在 HTML 頁(yè)面中點(diǎn)擊一個(gè)鏈接后定位到當(dāng)前網(wǎng)頁(yè)上的某個(gè) anchor。
要實(shí)現(xiàn)它,首先我們需要看 ScrollViewer 為我們提供的 API,其中并沒有類似于 ScrollToControl 這樣的方法;在它的幾個(gè)以 ScrollTo 開頭的方法中,最合適的就是 ScrollToVerticalOffset 這個(gè)方法了,這個(gè)方法接受一個(gè)參數(shù),即縱向的偏移位置。那么,很重要的問題:我們?cè)趺茨艿玫揭ㄎ坏哪莻€(gè)控件在 ScrollViewer 中的位置呢?
在我之前寫的這篇文章中:XAML: 獲取元素的位置,有如何獲到元素相對(duì)位置的介紹,建議大家先了解一下,其中使用了 Visual.TransformToVisual 方法等。當(dāng)你理解了這篇文章后,再回過頭來看本文后面的內(nèi)容,就很容易了。
接下來,我們使用以下代碼,即可實(shí)現(xiàn)上述需求:
// 獲取要定位之前 ScrollViewer 目前的滾動(dòng)位置 var currentScrollPosition = ScrollViewer.VerticalOffset; var point = new Point(0, currentScrollPosition); // 計(jì)算出目標(biāo)位置并滾動(dòng) var targetPosition = TargetControl.TransformToVisual(ScrollViewer).Transform(point); ScrollViewer.ScrollToVerticalOffset(targetPosition.Y);
另外,由于通常情況下,我們會(huì)采用 MVVM 模式,因此我們可以將上述代碼封裝成一個(gè) Action,而避免在 Code-Behind 代碼文件中添加上述代碼。
新創(chuàng)建的名為 ScrollToControlAction 的 Action,在其中定義兩個(gè)依賴屬性 ScrollViewer 和 TargetControl,分別表示指定的要操作的 ScrollViewer 和要定位到的控件,然后將上述代碼放到其 Invoke 方法中即可。由于 Action 并非本文主題,所以這里并不會(huì)展開太多的講解,可以參考以下代碼或本文后提供的 Demo 作進(jìn)一步了解。
namespace ScrollTest { /// <summary> /// 在 ScrollViewer 中定位到指定的控件 /// 說明:目前支持的是垂直滾動(dòng) /// </summary> public class ScrollToControlAction : TriggerAction<FrameworkElement> { public static readonly DependencyProperty ScrollViewerProperty = DependencyProperty.Register("ScrollViewer", typeof(ScrollViewer), typeof(ScrollToControlAction), new PropertyMetadata(null)); public static readonly DependencyProperty TargetControlProperty = DependencyProperty.Register("TargetControl", typeof(FrameworkElement), typeof(ScrollToControlAction), new PropertyMetadata(null)); /// <summary> /// 目標(biāo) ScrollViewer /// </summary> public ScrollViewer ScrollViewer { get { return (ScrollViewer)GetValue(ScrollViewerProperty); } set { SetValue(ScrollViewerProperty, value); } } /// <summary> /// 要定位的到的控件 /// </summary> public FrameworkElement TargetControl { get { return (FrameworkElement)GetValue(TargetControlProperty); } set { SetValue(TargetControlProperty, value); } } protected override void Invoke(object parameter) { if (TargetControl == null || ScrollViewer == null) { throw new ArgumentNullException($"{ScrollViewer} or {TargetControl} cannot be null"); } // 檢查指定的控件是否在指定的 ScrollViewer 中 // TODO: 這里只是指定離它最近的 ScrollViewer,并沒有繼續(xù)向上找 var container = TargetControl.FindParent<ScrollViewer>(); if (container == null || container != ScrollViewer) { throw new Exception("The TargetControl is not in the target ScrollViewer"); } // 獲取要定位之前 ScrollViewer 目前的滾動(dòng)位置 var currentScrollPosition = ScrollViewer.VerticalOffset; var point = new Point(0, currentScrollPosition); // 計(jì)算出目標(biāo)位置并滾動(dòng) var targetPosition = TargetControl.TransformToVisual(ScrollViewer).Transform(point); ScrollViewer.ScrollToVerticalOffset(targetPosition.Y); } } }
其使用方法如下:
<Button> <i:Interaction.Triggers> <i:EventTrigger EventName="Click"> <local:ScrollToControlAction ScrollViewer="{Binding ElementName=s}" TargetControl="{Binding ElementName=txtSectionC}" /> </i:EventTrigger> </i:Interaction.Triggers> </Button>
至此,結(jié)合 Action,我們以非常靈活的方式實(shí)現(xiàn)了本文所提出的需求。
以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
- WPF自定義控件和樣式之自定義按鈕(Button)
- WPF如何自定義TabControl控件樣式示例詳解
- 超炫酷的WPF實(shí)現(xiàn)Loading控件效果
- WPF的ListView控件自定義布局用法實(shí)例
- 在WPF中動(dòng)態(tài)加載XAML中的控件實(shí)例代碼
- C# 使用WPF 用MediaElement控件實(shí)現(xiàn)視頻循環(huán)播放
- WPF自定義TreeView控件樣式實(shí)現(xiàn)QQ聯(lián)系人列表效果
- WPF實(shí)現(xiàn)帶全選復(fù)選框的列表控件
- WPF開發(fā)技巧之花式控件功能擴(kuò)展詳解
相關(guān)文章
asp.net Gridview分頁(yè)保存選項(xiàng)
這篇文章介紹了asp.net Gridview分頁(yè)保存選項(xiàng),有需要的朋友可以參考一下2013-08-08ASP.net百度主動(dòng)推送功能實(shí)現(xiàn)代碼
百度站長(zhǎng)工具的主動(dòng)推送功能,以最為快速的提交方式,推薦您將站點(diǎn)當(dāng)天新產(chǎn)出鏈接立即通過此方式推送給百度,以保證新鏈接可以及時(shí)被百度收錄2020-09-09使用 ServiceStack.Text 序列化 json的實(shí)現(xiàn)代碼
今天發(fā)篇文章總結(jié)下自己使用 ServiceStack.Text 來序列化 json。它的速度比 Newtonsoft.Json 快很多,在測(cè)試時(shí)發(fā)現(xiàn)比 fastJson 還快些2013-06-06ASP.NET Core AutoWrapper 自定義響應(yīng)輸出實(shí)現(xiàn)
這篇文章主要介紹了ASP.NET Core AutoWrapper 自定義響應(yīng)輸出實(shí)現(xiàn),文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2020-08-08asp.net動(dòng)態(tài)獲取Excel表名的函數(shù)代碼
asp.net動(dòng)態(tài)獲取Excel表名的函數(shù)代碼,需要的朋友可以參考下。2011-02-02NET Core TagHelper實(shí)現(xiàn)分頁(yè)標(biāo)簽
這篇文章主要介紹了NET Core TagHelper實(shí)現(xiàn)分頁(yè)標(biāo)簽,講述實(shí)現(xiàn)一個(gè)簡(jiǎn)單分頁(yè)和總要注意步奏,感興趣的小伙伴們可以參考一下2016-07-07ASP.NET 廣告控件AdRotator的使用方法與實(shí)例
廣告控件是asp.net中一個(gè)獨(dú)有的東西,他可以利用asp.net來生成廣告控件所需的xml文檔,然后再利用AdRotator來調(diào)用廣告xml文件,根據(jù)我們的參考進(jìn)行顯示2013-08-08asp.net中javascript的引用(直接引入和間接引入)
Asp.net 中引入Javascript的方法有很多,個(gè)人認(rèn)為可以分為直接引入,和間接引入,下面是兩種具體的引用方法,感興趣的朋友可以參考下哈2013-06-06