private static SynchronizedScrollViewer FindSynchronizationScope(ScrollViewer target)
 {
     for (DependencyObject obj = target; obj != null;
          // ContentPresenter seems to cause VisualTreeHelper to return null when FrameworkElement.Parent works.
          // http://stackoverflow.com/questions/6921881/frameworkelement-parent-and-visualtreehelper-getparent-behaves-differently
          obj = VisualTreeHelper.GetParent(obj) ?? (obj as FrameworkElement)?.Parent)
     {
         var mode = GetScopeMode(obj);
         if (mode != SynchronizedScrollViewerMode.Disabled)
         {
             var scope = GetScope(obj);
             if (scope == null)
             {
                 scope = new SynchronizedScrollViewer(mode);
                 scope.HorizontalAlignment = GetHorizontalAlignment(obj);
                 scope.VerticalAlignment   = GetVerticalAlignment(obj);
                 SetScope(obj, scope);
             }
             return(scope);
         }
     }
     throw new InvalidOperationException("A scroll viewer is set as synchronized, but no synchronization scope was found.");
 }
 public static void SetScope(DependencyObject obj, SynchronizedScrollViewer value)
 {
     obj.SetValue(ScopeProperty, value);
 }