In front-end UI development, sometimes we encounter the need to have a lot of content in a ScrollViewer, and we need to implement the ability to locate the specified control after performing an operation; this is much like clicking a link in an HTML page to locate an anchor on the current web page.
To implement it, we first need to look at the API provided by ScrollViewer, which does not have methods similar to ScrollToControl; among its several methods starting with ScrollTo, the most suitable method is the ScrollToVerticalOffset, which accepts a parameter, that is, the vertical offset position. So, the very important question: How can we get the position of the control we want to locate in the ScrollViewer?
In this article I wrote:XAML: Get the location of the element, There is an introduction to how to obtain the relative position of elements. It is recommended that you understand first, which uses methods, etc. When you understand this article, it will be easy to look back at the contents later in this article.
Next, we can use the following code to achieve the above requirements:
// Get the current scroll position of the ScrollViewer before you want to locate var currentScrollPosition = ; var point = new Point(0, currentScrollPosition); // Calculate the target position and scroll var targetPosition = (ScrollViewer).Transform(point); ();
Also, since we usually use MVVM mode, we can wrap the above code into an Action and avoid adding the above code to the Code-Behind code file.
The newly created Action named ScrollToControlAction defines two dependencies, ScrollViewer and TargetControl, representing the specified ScrollViewer to operate and the control to be located, and then put the above code into its Invoke method. Since Action is not the topic of this article, there will be no explanation here. You can refer to the following code or the demo provided later in this article for further understanding.
namespace ScrollTest { /// <summary> /// Position the specified control in ScrollViewer /// Note: Currently, vertical scrolling is supported /// </summary> public class ScrollToControlAction : TriggerAction<FrameworkElement> { public static readonly DependencyProperty ScrollViewerProperty = ("ScrollViewer", typeof(ScrollViewer), typeof(ScrollToControlAction), new PropertyMetadata(null)); public static readonly DependencyProperty TargetControlProperty = ("TargetControl", typeof(FrameworkElement), typeof(ScrollToControlAction), new PropertyMetadata(null)); /// <summary> /// Target ScrollViewer /// </summary> public ScrollViewer ScrollViewer { get { return (ScrollViewer)GetValue(ScrollViewerProperty); } set { SetValue(ScrollViewerProperty, value); } } /// <summary> /// The control to be located /// </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"); } // Check whether the specified control is in the specified ScrollViewer // TODO: Here is just specifying the closest ScrollViewer to it, and it does not continue to look up var container = <ScrollViewer>(); if (container == null || container != ScrollViewer) { throw new Exception("The TargetControl is not in the target ScrollViewer"); } // Get the current scroll position of the ScrollViewer before you want to locate var currentScrollPosition = ; var point = new Point(0, currentScrollPosition); // Calculate the target position and scroll var targetPosition = (ScrollViewer).Transform(point); (); } } }
Its usage is as follows:
<Button> <i:> <i:EventTrigger EventName="Click"> <local:ScrollToControlAction ScrollViewer="{Binding ElementName=s}" TargetControl="{Binding ElementName=txtSectionC}" /> </i:EventTrigger> </i:> </Button>
At this point, combined with Action, we have achieved the requirements set out in this article in a very flexible way.
Source code download
The above is all the content of this article. I hope it will be helpful to everyone's study and I hope everyone will support me more.