国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁(yè) > 編程 > .NET > 正文

WPF實(shí)現(xiàn)ScrollViewer滾動(dòng)到指定控件處

2024-07-10 12:49:05
字體:
來(lái)源:轉(zhuǎn)載
供稿:網(wǎng)友

在前端 UI 開(kāi)發(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,其中并沒(méi)有類似于 ScrollToControl 這樣的方法;在它的幾個(gè)以 ScrollTo 開(kāi)頭的方法中,最合適的就是 ScrollToVerticalOffset 這個(gè)方法了,這個(gè)方法接受一個(gè)參數(shù),即縱向的偏移位置。那么,很重要的問(wèn)題:我們?cè)趺茨艿玫揭ㄎ坏哪莻€(gè)控件在 ScrollViewer 中的位置呢?

在我之前寫的這篇文章中:XAML: 獲取元素的位置,有如何獲到元素相對(duì)位置的介紹,建議大家先了解一下,其中使用了 Visual.TransformToVisual 方法等。當(dāng)你理解了這篇文章后,再回過(guò)頭來(lái)看本文后面的內(nèi)容,就很容易了。

接下來(lá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ì)展開(kāi)太多的講解,可以參考以下代碼或本文后提供的 Demo 作進(jìn)一步了解。

namespace ScrollTest{ /// <summary> /// 在 ScrollViewer 中定位到指定的控件 /// 說(shuō)明:目前支持的是垂直滾動(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,并沒(méi)有繼續(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); } }}            
發(fā)表評(píng)論 共有條評(píng)論
用戶名: 密碼:
驗(yàn)證碼: 匿名發(fā)表
主站蜘蛛池模板: 瑞安市| 探索| 桦川县| 陇南市| 滕州市| 金寨县| 成都市| 房产| 永宁县| 绍兴市| 永宁县| 上犹县| 时尚| 盘山县| 鄂托克旗| 简阳市| 禄劝| 土默特右旗| 张家界市| 小金县| 三台县| 洛浦县| 连山| 阜康市| 洪泽县| 车致| 禄丰县| 淄博市| 开化县| 黎城县| 揭东县| 龙游县| 娄烦县| 内江市| 定西市| 内黄县| 威信县| 小金县| 太和县| 灵璧县| 邮箱|