在不同的DataTemplates中创建的两个ScrollViewer之间共享Horizo​​ntalOffset

时间:2011-10-21 12:10:41

标签: wpf binding scrollviewer

我有两个ItemsControls,它们使用与ItemsSource相同的集合。 ItemsControls的ItemTemplates非常相似:两个DataTemplates中都有一个ScrollViewer。

问题:

如果我在第一个ItemsControl中生成的其中一个ScrollViewers中更改Horizo​​ntalOffset,如何将ScrollViewer从第二个ItemsControl(,它与DataContext 具有相同的对象)滚动到同一个Horizo​​ntalOffset?

2 个答案:

答案 0 :(得分:3)

如果您在Google上搜索WPF ScrollViewer Synchronization,您会获得很多好结果,例如this codeproject article

答案 1 :(得分:0)

正如雷切尔所说,关于你的问题可能有很多解决方案。但是,我所看到的东西对我来说有点复杂或不简单。所以,我这样想,这很简单,并且可以应用在VisualTree中具有ScrollViewer的所有控件。

以下代码假定在VisualTree中具有ScrollViewer的两个控件已在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);
    }
}