Synchronized scrolling of two ScrollViewers whenever any one is scrolled in wpf
One way to do this is using the ScrollChanged
event to update the other ScrollViewer
<ScrollViewer Name="sv1" Height="100"
HorizontalScrollBarVisibility="Auto"
ScrollChanged="ScrollChanged">
<Grid Height="1000" Width="1000" Background="Green" />
</ScrollViewer>
<ScrollViewer Name="sv2" Height="100"
HorizontalScrollBarVisibility="Auto"
ScrollChanged="ScrollChanged">
<Grid Height="1000" Width="1000" Background="Blue" />
</ScrollViewer>
private void ScrollChanged(object sender, ScrollChangedEventArgs e)
{
if (sender == sv1)
{
sv2.ScrollToVerticalOffset(e.VerticalOffset);
sv2.ScrollToHorizontalOffset(e.HorizontalOffset);
}
else
{
sv1.ScrollToVerticalOffset(e.VerticalOffset);
sv1.ScrollToHorizontalOffset(e.HorizontalOffset);
}
}
Synchronized scrolling of two ScrollViewers with different content sizes
You have to calculate the scrolling position in a fraction of the total:
After scrolloffset on sv1 changes try something like
var scFract = sv1.HorizontalOffset / sv1.ScrollableWith;
sv2.ScrollToHorizontalOffset(sv2.ScrollableWith * scFract);
How to synchronize two ScrollViewers?
I used ViewChanged from ScrollViewer. Everything worked fine for me. Here is the code from MainPage.xaml.cs:
protected override void OnNavigatedTo(NavigationEventArgs e)
{
var list = new List<int>();
for (int i = 0; i < 100; ++i)
{
list.Add(i);
}
ItemsControl1.ItemsSource = list;
ItemsControl2.ItemsSource = list;
}
private void ScrollViewer1_OnViewChanged(object sender, ScrollViewerViewChangedEventArgs e)
{
if (ScrollViewer1.VerticalOffset != ScrollViewer2.VerticalOffset)
{
ScrollViewer2.ScrollToVerticalOffset(ScrollViewer1.VerticalOffset);
}
}
private void ScrollViewer2_OnViewChanged(object sender, ScrollViewerViewChangedEventArgs e)
{
if (ScrollViewer1.VerticalOffset != ScrollViewer2.VerticalOffset)
{
ScrollViewer1.ScrollToVerticalOffset(ScrollViewer2.VerticalOffset);
}
}
And XAML code from MainPage.xaml
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="50"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<ScrollViewer Grid.Column="0"
x:Name="ScrollViewer1"
ViewChanged="ScrollViewer1_OnViewChanged">
<ItemsControl x:Name="ItemsControl1">
<ItemsControl.ItemTemplate>
<DataTemplate>
<TextBlock Text="{Binding}"/>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</ScrollViewer>
<ScrollViewer Grid.Column="2"
x:Name="ScrollViewer2"
ViewChanged="ScrollViewer2_OnViewChanged">
<ItemsControl x:Name="ItemsControl2">
<ItemsControl.ItemTemplate>
<DataTemplate>
<TextBlock Text="{Binding}"/>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</ScrollViewer>
</Grid>
Try this, hope it helps.
Synchronizing Two Rich Text Box Scroll bars in WPF
You can use the ScrollViewer.ScrollChanged
routed event to listen for scrolling changes. Example:
<UniformGrid Rows="1" Width="300" Height="150" >
<RichTextBox x:Name="_rich1"
VerticalScrollBarVisibility="Auto"
ScrollViewer.ScrollChanged="RichTextBox_ScrollChanged" />
<RichTextBox x:Name="_rich2"
VerticalScrollBarVisibility="Auto"
ScrollViewer.ScrollChanged="RichTextBox_ScrollChanged" />
</UniformGrid>
Then, in the event handler you do the actual synchronizing (code stolen from inspired by this other answer):
private void RichTextBox_ScrollChanged(object sender, ScrollChangedEventArgs e)
{
var textToSync = (sender == _rich1) ? _rich2 : _rich1;
textToSync.ScrollToVerticalOffset(e.VerticalOffset);
textToSync.ScrollToHorizontalOffset(e.HorizontalOffset);
}
How to link scrollbar and scrollviewer
Ok, solved this. Was actually quite straightforward.
Have since found Wpf binding to a function, which should help anyone else interested. Its VB but should be clear enough.
Cheers
Further to above: I subclassed ScrollBar and passed in the ScrollViewer I wanted to bind.
Seems to work ok.
public class ScrollViewerBoundScrollBar : ScrollBar
{
private ScrollViewer _scrollViewer;
public ScrollViewer BoundScrollViewer { get { return _scrollViewer; } set { _scrollViewer = value; UpdateBindings(); } }
public ScrollViewerBoundScrollBar( ScrollViewer scrollViewer, Orientation o ) : base()
{
this.Orientation = o;
BoundScrollViewer = _scrollViewer;
}
public ScrollViewerBoundScrollBar() : base()
{
}
private void UpdateBindings()
{
this.AddHandler(ScrollBar.ScrollEvent, new ScrollEventHandler(OnScroll));
_scrollViewer.AddHandler(ScrollViewer.ScrollChangedEvent, new ScrollChangedEventHandler(BoundScrollChanged));
this.Minimum = 0;
if (Orientation == Orientation.Horizontal)
{
this.SetBinding(ScrollBar.MaximumProperty, (new Binding("ScrollableWidth") { Source = _scrollViewer, Mode = BindingMode.OneWay }));
this.SetBinding(ScrollBar.ViewportSizeProperty, (new Binding("ViewportWidth") { Source = _scrollViewer, Mode = BindingMode.OneWay }));
}
else
{
this.SetBinding(ScrollBar.MaximumProperty, (new Binding("ScrollableHeight") { Source = _scrollViewer, Mode = BindingMode.OneWay }));
this.SetBinding(ScrollBar.ViewportSizeProperty, (new Binding("ViewportHeight") { Source = _scrollViewer, Mode = BindingMode.OneWay }));
}
this.LargeChange = 242;
this.SmallChange = 16;
}
public void BoundScrollChanged(object sender, ScrollChangedEventArgs e)
{
switch (this.Orientation)
{
case Orientation.Horizontal:
this.Value = e.HorizontalOffset;
break;
case Orientation.Vertical:
this.Value = e.VerticalOffset;
break;
default:
break;
}
}
public void OnScroll(object sender, ScrollEventArgs e)
{
switch(this.Orientation)
{
case Orientation.Horizontal:
this.BoundScrollViewer.ScrollToHorizontalOffset(e.NewValue);
break;
case Orientation.Vertical:
this.BoundScrollViewer.ScrollToVerticalOffset(e.NewValue);
break;
default:
break;
}
}
}
Related Topics
Optimal Way to Read an Excel File (.Xls/.Xlsx)
How to Create a Xsd Schema from a Class
How to Use the C#6 "Using Static" Feature
How to Stop Flickering C# Winforms
How to Check If Two Expression<Func<T, Bool>> Are the Same
Compare Nullable Types in Linq to SQL
Pattern for Calling Wcf Service Using Async/Await
Detecting Network Connection Speed and Bandwidth Usage in C#
How to Get the Width and Height of a Multi-Dimensional Array
How to Extract Text from Ms Office Documents in C#
What's the Difference Between the Webconfigurationmanager and the Configurationmanager
How to Return a Custom Http Status Code from a Wcf Rest Method
Dependency Injection Using Azure Webjobs Sdk
How to Dispose My Filestream When Implementing a File Download in ASP.NET
How to Get the Last Five Characters of a String Using Substring() in C#
Get Ssid of the Wireless Network I am Connected to with C# .Net on Windows Vista