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);
 }