Reputation: 522
Right now I have two scrollviewers who both need to have the same offset at all time.
The (working) solution I have right now is with the ScrollChanged event. If the ScrollChanged event is triggered this code is executed:
scrollViewer.ScrollToHorizontalOffset(offset.X);
scrollViewer.ScrollToVerticalOffset(offset.Y);
The fact is, I want to try to avoid this code-behind solution.
I think the best solution for this problem is something like this (binding):
<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>
Now, when I try to build I got a few errors (HorizontalOffset/VerticalOffset cannot be set because it does not have an accesible set accessor).
Anyone knows if this is the best solution and how to handle the error? Or should I stay with the code-behind event?
Thanks
Upvotes: 3
Views: 1135
Reputation: 69979
While there is nothing wrong with using code behind in this situation, it is often customary to encapsulate event handling into Attached Properties when using WPF with MVVM. So, if you really wanted to get rid of the code behind, you could do this. Please refer to the Attached Properties Overview page on MSDN for a detailed description of Attached Properties.
In your case, you could do something like this:
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);
}
}
If this was in a class named ScrollViewerProperties
with an Xml Namespace Prefix of Attached
, then you could use it like this:
<ScrollViewer Name="ScrollViewerToLinkWith" ... />
...
<ScrollViewer Attached:ScrollViewerProperties.LinkedScrollViewer="{Binding
ElementName=ScrollViewerToLinkWith}" ... />
Now I can't check this at the moment, so you might have to tweak it, but it looks about right. Furthermore, you can handle just about any UI event like this.
Upvotes: 2