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

发布于 2024-12-11 14:08:56 字数 326 浏览 0 评论 0原文

我有两个 ItemsControl,它们使用与 ItemsSource 相同的集合。两个 ItemsControl 的 ItemTemplate 非常相似:两个 DataTemplate 内都有一个 ScrollViewer。

问题:

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

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?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

撩心不撩汉 2024-12-18 14:08:56

如果您在 Google 上搜索 WPF ScrollViewer Synchronization,您会得到很多好的结果,例如 这篇代码项目文章

If you do a Google search for WPF ScrollViewer Synchronization you'll get a lot of good results, such as this codeproject article

木緿 2024-12-18 14:08:56

正如雷切尔提到的,您的问题可能有很多解决方案。然而,我所看到的事情对我来说有点复杂或不简单。于是,我就这样想了,非常简单,可以应用VisualTree中所有有ScrollViewer的控件。

以下代码假设 VisualTree 中具有 ScrollViewer 的两个控件已在 Xaml 中定义,在我的代码中分别命名为 control1control2

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

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);
    }
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文