http://www.gbogea.com/2009/07/08/how-to-keep-two-scrollviewers-in-sync-in-wpf
there is the code. will copy paste here as mirror if the site goes down:
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="1*" />
<ColumnDefinition Width="1*" />
<ColumnDefinition Width="1*" />
</Grid.ColumnDefinitions>
<ScrollViewer Grid.Column="0" Name="scrollViewerLeft" ScrollChanged="scrollViewerLeft_ScrollChanged">
<ListBox>
<ListBoxItem>1</ListBoxItem>
<ListBoxItem>2</ListBoxItem>
<ListBoxItem>3</ListBoxItem>
...
<ListBoxItem>100</ListBoxItem>
</ListBox>
</ScrollViewer>
<ScrollViewer Grid.Column="1" Name="scrollViewerMiddle">
<ListBox>
<ListBoxItem>1</ListBoxItem>
<ListBoxItem>2</ListBoxItem>
<ListBoxItem>3</ListBoxItem>
...
<ListBoxItem>100</ListBoxItem>
</ListBox>
</ScrollViewer>
<ScrollViewer Grid.Column="2" Name="scrollViewerRight">
<ListBox>
<ListBoxItem>1</ListBoxItem>
<ListBoxItem>2</ListBoxItem>
<ListBoxItem>3</ListBoxItem>
...
<ListBoxItem>100</ListBoxItem>
</ListBox>
</ScrollViewer>
</Grid>
and the code behind:
private void scrollViewerLeft_ScrollChanged(object sender, ScrollChangedEventArgs e)
{
scrollViewerMiddle.ScrollToVerticalOffset((sender as ScrollViewer).VerticalOffset);
scrollViewerRight.ScrollToVerticalOffset((sender as ScrollViewer).VerticalOffset);
}
private void scrollViewerMiddle_ScrollChanged(object sender, ScrollChangedEventArgs e)
{
scrollViewerLeft.ScrollToVerticalOffset((sender as ScrollViewer).VerticalOffset);
scrollViewerRight.ScrollToVerticalOffset((sender as ScrollViewer).VerticalOffset);
}
private void scrollViewerRight_ScrollChanged(object sender, ScrollChangedEventArgs e)
{
scrollViewerLeft.ScrollToVerticalOffset((sender as ScrollViewer).VerticalOffset);
scrollViewerMiddle.ScrollToVerticalOffset((sender as ScrollViewer).VerticalOffset);
}