同步两个ScrollViewers之间的偏移量

时间:2014-01-10 08:38:17

标签: c# wpf binding synchronization scrollviewer

现在我有两个滚动查看器,它们都需要始终具有相同的偏移量。

我现在拥有的(工作)解决方案是使用ScrollChanged事件。 如果触发了ScrollChanged事件,则执行此代码:

scrollViewer.ScrollToHorizontalOffset(offset.X);
scrollViewer.ScrollToVerticalOffset(offset.Y);

事实是,我想尽量避免这种代码隐藏解决方案。

我认为这个问题的最佳解决方案是这样的(绑定):

 <ScrollViewer x:Name="scrollviewer_Top" HorizontalOffset="{Binding ElementName=scrollViewer_Center, Path=HorizontalOffset}">...</ScrollViewer>

 <ScrollViewer x:Name="scrollViewer_Left" VerticalOffset="{Binding ElementName=scrollViewer_Center, Path=VerticalOffset}" >...</ScrollViewer>

 <ScrollViewer x:Name="scrollViewer_Center" HorizontalOffset="{Binding ElementName=scrollviewer_Top, Path=HorizontalOffset}"
                                  VerticalOffset="{Binding ElementName=scrollViewer_Left, Path=VerticalOffset}">...</ScrollViewer>

现在,当我尝试构建时,我遇到了一些错误(无法设置Horizo​​ntalOffset / VerticalOffset,因为它没有可访问的set访问器)。

任何人都知道这是否是最佳解决方案以及如何处理错误?或者我应该继续使用代码隐藏事件?

由于

1 个答案:

答案 0 :(得分:1)

虽然在这种情况下使用代码背后没有任何问题,但在将WPF与MVVM一起使用时,通常会将事件处理封装到附加属性中。所以,如果真的想要摆脱背后的代码,你可以做到这一点。有关附加属性的详细说明,请参阅MSDN上的Attached Properties Overview页面。

在你的情况下,你可以这样做:

public static readonly DependencyProperty LinkedScrollViewerProperty = DependencyProperty.RegisterAttached("LinkedScrollViewer", typeof(ScrollViewer), typeof(ScrollViewerProperties), new UIPropertyMetadata(null, OnLinkedScrollViewerChanged));

public static ScrollViewer GetLinkedScrollViewer(DependencyObject dependencyObject)
{
    return (ScrollViewer)dependencyObject.GetValue(LinkedScrollViewerProperty);
}

public static void SetLinkedScrollViewer(DependencyObject dependencyObject, ScrollViewer value)
{
    dependencyObject.SetValue(LinkedScrollViewerProperty, value);
}

public static void OnLinkedScrollViewerChanged(DependencyObject dependencyObject, DependencyPropertyChangedEventArgs e)
{
    ScrollViewer scrollViewer = (ScrollViewer)dependencyObject;
    ScrollViewer newLinkedScrollViewer = e.NewValue as ScrollViewer;
    if (newLinkedScrollViewer != null)
    {
        newLinkedScrollViewer.ScrollToHorizontalOffset(scrollViewer.HorizontalOffset);
        newLinkedScrollViewer.ScrollToVerticalOffset(scrollViewer.VerticalOffset);
    }
}

如果这是一个名为ScrollViewerProperties的类,其Xml命名空间前缀为Attached,那么您可以像这样使用它:

<ScrollViewer Name="ScrollViewerToLinkWith" ... />
...
<ScrollViewer Attached:ScrollViewerProperties.LinkedScrollViewer="{Binding 
    ElementName=ScrollViewerToLinkWith}" ... />

现在我无法检查这一点,所以你可能需要调整它,但它看起来是正确的。此外,您可以处理任何类似的UI事件。