You can trick the datagrid to open your ScrollViewer as a public property for each grid when, for example, it called the innerGridControl_ScrollChanged () handler during usercontrol initialization. To open it, you can make your grid in a xaml View file, and then compose two of them in a different xaml view. Below code is on innerGrid.xaml.cs, for example:
public ScrollViewer Scroller { get; set; } // exposed ScrollViewer from the grid private bool _isFirstTimeLoaded = true; private void innerGridControl_ScrollChanged(object sender, ScrollChangedEventArgs e) { if (_isFirstTimeLoaded) // just to save the code from casting and assignment after 1st time loaded { var scroller = (e.OriginalSource) as ScrollViewer; Scroller = scroller; _isFirstTimeLoaded = false; } }
in OuterGridView.xaml puts the definition of the attached event handler:
<Views:innerGridView Grid.Row="1" Margin="2,0,2,2" DataContext="{Binding someCollection}" x:Name="grid1Control" ScrollViewer.ScrollChanged="Grid1Attached_ScrollChanged" ></Views:innerGridView> <Views:innerGridView Grid.Row="3" Margin="2,0,2,2" DataContext="{Binding someCollection}" x:Name="grid2Control" ScrollViewer.ScrollChanged="Grid2Attached_ScrollChanged" ></Views:innerGridView>
then go into this public ScrollViewer.SetHorizontalOffset (e.HorizontalOffset) method when another scroll event occurs. Below code is in OuterGridView.xaml.cs in one of the handler definitions (
private void Grid1Attached_ScrollChanged(object sender, ScrollChangedEventArgs e) { if (e != null && !e.Handled) { if (e.HorizontalChange != 0.0) { grid2Control.Scroller.ScrollToHorizontalOffset(e.HorizontalOffset); } e.Handled = true; } } private void Grid2Attached_ScrollChanged(object sender, ScrollChangedEventArgs e) { if (e != null && !e.Handled) { if (e.HorizontalChange != 0.0) { grid1Control.Scroller.ScrollToHorizontalOffset(e.HorizontalOffset); } e.Handled = true; } }
Also make sure that any other scroll_changed event is inside the internal grid (if there is, for example, if you define a TextBox with a default scroller in one of the column data templates), its e.Handled is set to true to prevent it from processing the external grid handler (this was due to the default bubbling behavior of routedevents). Alternatively, you can add additional data if checking for e.OriginalSource or e.Source to filter the scroll event that you are going to handle.
mithocondria
source share