Advertisement
bobmarley12345

WPF scroll offset binder

Jul 12th, 2023
803
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C# 5.20 KB | None | 0 0
  1. using System.Collections.Generic;
  2. using System.Windows;
  3. using System.Windows.Controls;
  4.  
  5. namespace FramePFX.Converters {
  6.     public static class ScrollBinder {
  7.         public static readonly DependencyProperty VerticalBindGroupProperty =
  8.             DependencyProperty.RegisterAttached(
  9.                 "VerticalBindGroup",
  10.                 typeof(string),
  11.                 typeof(ScrollBinder),
  12.                 new FrameworkPropertyMetadata(null, FrameworkPropertyMetadataOptions.BindsTwoWayByDefault, OnVerticalBindGroupPropertyChanged));
  13.  
  14.         public static readonly DependencyProperty HorizontalBindGroupProperty =
  15.             DependencyProperty.RegisterAttached(
  16.                 "HorizontalBindGroup",
  17.                 typeof(string),
  18.                 typeof(ScrollBinder),
  19.                 new FrameworkPropertyMetadata(null, FrameworkPropertyMetadataOptions.BindsTwoWayByDefault, OnHorizontalBindGroupPropertyChanged));
  20.  
  21.         public static void SetVerticalBindGroup(DependencyObject element, string value) => element.SetValue(VerticalBindGroupProperty, value);
  22.         public static string GetVerticalBindGroup(DependencyObject element) => (string) element.GetValue(VerticalBindGroupProperty);
  23.  
  24.         public static void SetHorizontalBindGroup(DependencyObject element, string value) => element.SetValue(HorizontalBindGroupProperty, value);
  25.         public static string GetHorizontalBindGroup(DependencyObject element) => (string) element.GetValue(HorizontalBindGroupProperty);
  26.  
  27.         private static bool IsUpdatingScroll;
  28.         private static readonly Dictionary<string, List<ScrollViewer>> RegisteredScrollers = new Dictionary<string, List<ScrollViewer>>();
  29.  
  30.         private static void OnVerticalBindGroupPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) {
  31.             if (d is ScrollViewer scroller) {
  32.                 if (e.OldValue is string oldGroup) {
  33.                     if (RegisteredScrollers.TryGetValue(oldGroup, out var list)) {
  34.                         list.Remove(scroller);
  35.                     }
  36.                 }
  37.  
  38.                 scroller.ScrollChanged -= OnVerticalScrollChanged;
  39.                 if (e.NewValue is string newGroup) {
  40.                     scroller.ScrollChanged += OnVerticalScrollChanged;
  41.                     if (!RegisteredScrollers.TryGetValue(newGroup, out List<ScrollViewer> list)) {
  42.                         RegisteredScrollers[newGroup] = list = new List<ScrollViewer>();
  43.                     }
  44.  
  45.                     list.Add(scroller);
  46.                 }
  47.             }
  48.         }
  49.  
  50.         private static void OnVerticalScrollChanged(object sender, ScrollChangedEventArgs e) {
  51.             if (IsUpdatingScroll) {
  52.                 return;
  53.             }
  54.  
  55.             ScrollViewer viewer = (ScrollViewer) sender;
  56.             string group = GetVerticalBindGroup(viewer);
  57.             if (group == null) {
  58.                 return;
  59.             }
  60.  
  61.             if (RegisteredScrollers.TryGetValue(group, out var list)) {
  62.                 IsUpdatingScroll = true;
  63.                 try {
  64.                     foreach (ScrollViewer scrollViewer in list) {
  65.                         if (scrollViewer != viewer) {
  66.                             scrollViewer.ScrollToVerticalOffset(e.VerticalOffset);
  67.                         }
  68.                     }
  69.                 }
  70.                 finally {
  71.                     IsUpdatingScroll = false;
  72.                 }
  73.             }
  74.         }
  75.  
  76.         private static void OnHorizontalBindGroupPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) {
  77.             if (d is ScrollViewer scroller) {
  78.                 if (e.OldValue is string oldGroup) {
  79.                     if (RegisteredScrollers.TryGetValue(oldGroup, out var list)) {
  80.                         list.Remove(scroller);
  81.                     }
  82.                 }
  83.  
  84.                 scroller.ScrollChanged -= OnHorizontalScrollChanged;
  85.                 if (e.NewValue is string newGroup) {
  86.                     scroller.ScrollChanged += OnHorizontalScrollChanged;
  87.                     if (!RegisteredScrollers.TryGetValue(newGroup, out List<ScrollViewer> list)) {
  88.                         RegisteredScrollers[newGroup] = list = new List<ScrollViewer>();
  89.                     }
  90.  
  91.                     list.Add(scroller);
  92.                 }
  93.             }
  94.         }
  95.  
  96.         private static void OnHorizontalScrollChanged(object sender, ScrollChangedEventArgs e) {
  97.             if (IsUpdatingScroll) {
  98.                 return;
  99.             }
  100.  
  101.             ScrollViewer viewer = (ScrollViewer) sender;
  102.             string group = GetHorizontalBindGroup(viewer);
  103.             if (group == null) {
  104.                 return;
  105.             }
  106.  
  107.             if (RegisteredScrollers.TryGetValue(group, out var list)) {
  108.                 IsUpdatingScroll = true;
  109.                 try {
  110.                     foreach (ScrollViewer scrollViewer in list) {
  111.                         if (scrollViewer != viewer) {
  112.                             scrollViewer.ScrollToHorizontalOffset(e.HorizontalOffset);
  113.                         }
  114.                     }
  115.                 }
  116.                 finally {
  117.                     IsUpdatingScroll = false;
  118.                 }
  119.             }
  120.         }
  121.     }
  122. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement