WPF/MVVM: 在不同视图中同步滚动两个数据网格

9

我有两个并排的数据表,分别绑定到不同的数据表且拥有各自的视图。

这两个数据表都拥有相同数量的行,我想让两个表格保持相同的滚动位置。

使用MVVM我一直找不到方法来实现这个功能... 有人有什么想法吗?

谢谢! -Steven

4个回答

8

通过一些反射技巧,我成功地解决了这个问题:

<DataGrid Name="DataGrid1" ScrollViewer.ScrollChanged="DataGrid1_ScrollChanged" />
<DataGrid Name="DataGrid2" />

代码本身是:

    private void DataGrid1_ScrollChanged(object sender, ScrollChangedEventArgs e)
    {
        if (e.HorizontalChange != 0.0f)
        {
            ScrollViewer sv = null;
            Type t = DataGrid1.GetType();
            try
            {
                sv = t.InvokeMember("InternalScrollHost", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.GetProperty, null, DataGrid2, null) as ScrollViewer;
                sv.ScrollToHorizontalOffset(e.HorizontalOffset);
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message);
            }
        }
    }

1
+1 反射黑客技巧。结合 CodeProject 文章使用,实现了 WPF Datagrid 的工作附加属性。 - Dr. Andrew Burnett-Thompson

8

谢谢您的快速回复!这正是我所需要的,我已经实现并且运行良好 :) - stevosaurus

4

由于Datagrid不公开ScrollToVerticalOffset,因此滚动同步项目无法用于Datagrid。


0
到目前为止,我使用的最好方法是使用VisualTreeHelper类来查找正确的ScrollViewer对象(无论是网格还是非网格)。我在几个项目中都使用了这种方法。
如果有人需要,请尝试一下:
private static bool ScrollToOffset(DependencyObject n, double offset)
{
    bool terminate = false;
    for (int i = 0; i < VisualTreeHelper.GetChildrenCount(n); i++)
    {
        var child = VisualTreeHelper.GetChild(n, i);
        if (child is ScrollViewer)
        {
            (child as ScrollViewer).ScrollToVerticalOffset(offset);
            return true;
        }
    }
    if (!terminate)
        for (int i = 0; i < VisualTreeHelper.GetChildrenCount(n); i++)
            terminate = ScrollToOffset(VisualTreeHelper.GetChild(n, i), offset);
     return false;
}

注意:我通常使用ListBox类,并直接将其传递给此函数。
愉快的编程 :)

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接