WPF implements scrollviewer to scroll to the specified control

Time:2021-7-30

In front-end UI development, we sometimes encounter such requirements: there are many contents in a scrollviewer, and we need to be able 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, first we need to look at the API provided by scrollviewer. There is no method like scrolltocontrol; Among its several methods starting with scrollto, the most appropriate is the scrolltoverticaloffset method, which accepts a parameter, that is, the vertical offset position. So, a very important question: how can we get the position of the control to be located in the scrollviewer?

In my previous article:Xaml: get the location of the element, there is an introduction to how to get the relative position of elements. I suggest you learn about it first, in which the visual. Transformtovisual method is used. When you understand this article, it’s easy to look back at the rest of this article.

Next, we use the following code to achieve the above requirements:

//Gets the current scroll position of the scrollviewer before you want to locate it
 var currentScrollPosition = ScrollViewer.VerticalOffset;
 var point = new Point(0, currentScrollPosition);

 //Calculate the target position and scroll
 var targetPosition = TargetControl.TransformToVisual(ScrollViewer).Transform(point);
 ScrollViewer.ScrollToVerticalOffset(targetPosition.Y);

In addition, since we usually adopt MVVM mode, we can encapsulate the above code into an action and avoid adding the above code to the code behind code file.

The newly created action named scrolltocontrocaction defines two dependent properties scrollviewer and targetcontrol, which respectively represent the specified scrollviewer to operate and the control to locate, and then put the above code into its invoke method. Since action is not the subject of this article, there will not be much explanation here. You can refer to the following code or the demo provided later in this article for further understanding.

namespace ScrollTest
{
 /// <summary>
 ///Navigate to the specified control in the scrollviewer
 ///Note: vertical scrolling is currently supported
 /// </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>
 ///Target scrollviewer
 /// </summary>
 public ScrollViewer ScrollViewer
 {
 get { return (ScrollViewer)GetValue(ScrollViewerProperty); }
 set { SetValue(ScrollViewerProperty, value); }
 }

 /// <summary>
 ///Control to navigate to
 /// </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");
 }

 //Checks whether the specified control is in the specified scrollviewer
 //Todo: Here we just specify the scrollviewer closest to it, and do not continue to look up
 var container = TargetControl.FindParent<ScrollViewer>();
 if (container == null || container != ScrollViewer)
 {
 throw new Exception("The TargetControl is not in the target ScrollViewer");
 }

 //Gets the current scroll position of the scrollviewer before you want to locate it
 var currentScrollPosition = ScrollViewer.VerticalOffset;
 var point = new Point(0, currentScrollPosition);

 //Calculate the target position and scroll
 var targetPosition = TargetControl.TransformToVisual(ScrollViewer).Transform(point);
 ScrollViewer.ScrollToVerticalOffset(targetPosition.Y);
 }
 }
}

Its use method is as follows:


<Button>
 <i:Interaction.Triggers>
  <i:EventTrigger EventName="Click">
  <local:ScrollToControlAction ScrollViewer="{Binding ElementName=s}" TargetControl="{Binding ElementName=txtSectionC}" />
  </i:EventTrigger>
 </i:Interaction.Triggers>
</Button>

So far, combined with action, we have implemented the requirements proposed in this paper in a very flexible way.

Source download

The above is the whole content of this article. I hope it will be helpful to your study, and I hope you can support developpaer.

Recommended Today

JS generate guid method

JS generate guid method https://blog.csdn.net/Alive_tree/article/details/87942348 Globally unique identification(GUID) is an algorithm generatedBinaryCount Reg128 bitsNumber ofidentifier , GUID is mainly used in networks or systems with multiple nodes and computers. Ideally, any computational geometry computer cluster will not generate two identical guids, and the total number of guids is2^128In theory, it is difficult to make two […]