Совместное использование HorizontalOffset между двумя ScrollViewer, созданными в разных шаблонах данных

У меня есть два ItemsControls, которые используют ту же коллекцию, что и ItemsSource. ItemTemplates для обоих ItemsControls очень похожи: внутри обоих DataTemplates есть ScrollViewer.

Вопрос:

Если я изменю HorizontalOffset в одном из ScrollViewer, сгенерированных в первом ItemsControl, как я могу прокрутить ScrollViewer из второго ItemsControl, который имеет тот же объект, что и DataContext, в тот же HorizontalOffset?

2 ответа

Решение

Как упоминала Рейчел, может быть много решений по вашей проблеме. Тем не менее, вещи, которые я видел, немного сложны или не просты для меня. Итак, я подумал так, что это очень просто и может применить весь элемент управления, который имеет ScrollViewer в VisualTree.

В следующем коде предполагается, что два элемента управления, имеющие ScrollViewer в VisualTree, уже определены в Xaml, которые в моем коде называются control1 и control2.

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

Если вы делаете поиск Google для WPF ScrollViewer Synchronization вы получите много хороших результатов, таких как эта статья

Другие вопросы по тегам