Question: I've got two ItemsControls, which use the same collection as an ItemsSource. ItemTemplates for both ItemsControls are very similar: there is a ScrollViewer inside both DataTemplates.

**Question:**

If I change HorizontalOffset in one of the ScrollViewers generated in the first ItemsControl, how can I scroll the ScrollViewer from the second ItemsControl, **which has the same object as a DataContext**, to the same HorizontalOffset?

Answer: 
If you do a Google search for `WPF ScrollViewer Synchronization` you'll get a lot of good results, such as [this codeproject article](http://www.codeproject.com/KB/WPF/ScrollSynchronization.aspx)
As Rachel mentioned, there may be lots of solutions about your problem. However, the things that I have seen are a little complex or not simple for me. So, I thought this way, which is very simple and can apply all the control which has ScrollViewer in VisualTree.

The following code assumes that the two controls, having ScrollViewer in VisualTree, are already defined in Xaml, which are named **control1** and **control2** in my code.

```
public partial class MainWindow : Window
{
    private ScrollViewer _scrollViewer1;
    private ScrollViewer _scrollViewer2;

    public MainWindow()
    {
        InitializeComponent();
        Loaded += (s, e) =>
                    {
                        _scrollViewer1 = FindScrollViewer(**control1**);
                        _scrollViewer2 = FindScrollViewer(**control2**);
                        if (_scrollViewer1 == null || _scrollViewer2 == null) throw new InvalidOperationException();
                        _scrollViewer1.ScrollChanged += ScrollViewer1ScrollChanged;
                        _scrollViewer2.ScrollChanged += ScrollViewer2ScrollChanged;
                    };
    }

    private ScrollViewer FindScrollViewer(Visual visual)
    {
        for (int i = 0; i < VisualTreeHelper.GetChildrenCount(visual); i++)
        {
            var visualChild = VisualTreeHelper.GetChild(visual, i) as Visual;
            if (visualChild == null) continue;
            var scrollViewer = visualChild as ScrollViewer;
            if (scrollViewer != null)
            {
                return scrollViewer;
            }
            return FindScrollViewer(visualChild);
        }
        return null;
    }

    private void ScrollViewer1ScrollChanged(object sender, ScrollChangedEventArgs e)
    {
        _scrollViewer2.ScrollToVerticalOffset(_scrollViewer1.VerticalOffset);
    }

    private void ScrollViewer2ScrollChanged(object sender, ScrollChangedEventArgs e)
    {
        _scrollViewer1.ScrollToVerticalOffset(_scrollViewer2.VerticalOffset);
    }
}

```