none
WPF two Datagrid with same Scrolling

    Question

  • Hi

         In my WPF Application I have  two Datagrids in a window, when user Scroll any one datagrid the another datagrid also should automatically scroll with that same position, this is what my requirement. I tried lot but I couldn't achieve the same.

    Can any once please help me.

    Thanks in Advance

    Selvakumar Rathinam

     


    Selvakumar Rathinam Team Lead
    Monday, October 31, 2011 1:20 AM

Answers

  • Yeah, I am thinking about both horizonal and vertical scroll bars.

    Actually, there is a kind of funny way of dealing with this, assuming everyting is the same as I mentioned

    Binding the VerticalOffset/HorizontalOffset property from on data grid to the other one, sort of funny to see both offsetting in sync :)

    Monday, October 31, 2011 5:39 AM
  • Horizontal would be interesting if there were different columns being shown. Though I suppose one could relatively easily calculate the ratio for the offset based on the ScrollableWidth/ScrollableHeight properties...
    Monday, October 31, 2011 11:27 PM
  • Hi Selvakumar,

    Thank you for your post.

    According to your description, I understand you want when user Scroll any one datagrid the another datagrid also should automatically scroll with that same position.

    What Johnny and Matt said is correct. Have you resolved your issue? 

    Also,please check out below link about Scroll Synchronization for your reference:

    http://www.codeproject.com/KB/WPF/ScrollSynchronization.aspx

    If you have any additional questions, please feel free to let me know.

    Have a nice day. 

     


    Annabella Luo [MSFT]
    MSDN Community Support | Feedback to us
    Get or Request Code Sample from Microsoft
    Please remember to mark the replies as answers if they help and unmark them if they provide no help.


    Wednesday, November 02, 2011 3:05 AM

All replies

  • Hi,

    Are those two data grids having the same data source?

    Monday, October 31, 2011 1:27 AM
  • Give this a go.

    <Grid>
            <Grid.ColumnDefinitions>
                <ColumnDefinition></ColumnDefinition>
                <ColumnDefinition></ColumnDefinition>
            </Grid.ColumnDefinitions>
            <DataGrid x:Name="dataGridRight" Grid.Column="0" ItemsSource="{Binding MyItems}">
                <DataGrid.Columns>
                    <DataGridTextColumn Header="Value" Binding="{Binding }"></DataGridTextColumn>
                </DataGrid.Columns>
            </DataGrid>
            <DataGrid x:Name="dataGridLeft" Grid.Column="1" ItemsSource="{Binding MyItems}">
                <DataGrid.Columns>
                    <DataGridTextColumn Header="Value" Binding="{Binding }"></DataGridTextColumn>
                </DataGrid.Columns>
            </DataGrid>
        </Grid>
    
    


     public partial class MainWindow : Window
        {
            public List<string> MyItems { get; set; }
            private ScrollViewer _leftScrollViewer;
            private ScrollViewer _rightScrollViewer;
    
            public MainWindow()
            {
                InitializeComponent();
    
                this.DataContext = this;
    
                MyItems = new List<string>(Enumerable.Range(0, 100).Select(x => x.ToString()) );            
    
                this.Loaded += new RoutedEventHandler(MainWindow_Loaded);
            }
    
            void MainWindow_Loaded(object sender, RoutedEventArgs e)
            {
                _rightScrollViewer = ScrollViewerFromFrameworkElement(dataGridRight);
                _leftScrollViewer = ScrollViewerFromFrameworkElement(dataGridLeft);
    
                _rightScrollViewer.ScrollChanged += new ScrollChangedEventHandler(scrollViewer_RightScrollChanged);
                _leftScrollViewer.ScrollChanged += new ScrollChangedEventHandler(scrollViewer_LeftScrollChanged);
            }
    
            void scrollViewer_RightScrollChanged(object sender, ScrollChangedEventArgs e)
            {
                if (_leftScrollViewer.VerticalOffset != _rightScrollViewer.VerticalOffset)
                {
                    _leftScrollViewer.ScrollToVerticalOffset(_rightScrollViewer.VerticalOffset);
                }
            }
    
            void scrollViewer_LeftScrollChanged(object sender, ScrollChangedEventArgs e)
            {
                if (_rightScrollViewer.VerticalOffset != _leftScrollViewer.VerticalOffset)
                {
                    _rightScrollViewer.ScrollToVerticalOffset(_leftScrollViewer.VerticalOffset);
                }
            }
    
    
            ScrollViewer ScrollViewerFromFrameworkElement(FrameworkElement frameworkElement)
            {                        
                if (VisualTreeHelper.GetChildrenCount(frameworkElement) == 0) return null;
    
                FrameworkElement child = VisualTreeHelper.GetChild(frameworkElement, 0) as FrameworkElement;
    
                if (child == null) return null;
    
                if (child is ScrollViewer)
                {
                    return (ScrollViewer)child;
                }
    
                return ScrollViewerFromFrameworkElement(child);
            }      
        }
    
    


    Warm regards,

    Matt

    Monday, October 31, 2011 4:39 AM
  • I did something like that but

    1. Both data grids have to exactly the same size and the same re-size behavior (stretch, scale, transform etc.)

    2. Both data grids have to have exactly the same items displayed (data template, filter, grouping etc.)

    The scroll viewer in the data template depends on the child visual item of itself to provide scrolling and offset.

    Then I realized those assumptions might not even be approperiate depends on the use cases.

    Monday, October 31, 2011 5:06 AM
  • @Johnny CH

     

    All very true, but hopefully that's enough to give Selvakumar Rathinam a starting point :) Filtering and grouping should be happening at the ItemsSource, and as long as the number of rows and each of their heights are the same, this solution should be alright.


    Monday, October 31, 2011 5:21 AM
  • Yeah, I am thinking about both horizonal and vertical scroll bars.

    Actually, there is a kind of funny way of dealing with this, assuming everyting is the same as I mentioned

    Binding the VerticalOffset/HorizontalOffset property from on data grid to the other one, sort of funny to see both offsetting in sync :)

    Monday, October 31, 2011 5:39 AM
  • Horizontal would be interesting if there were different columns being shown. Though I suppose one could relatively easily calculate the ratio for the offset based on the ScrollableWidth/ScrollableHeight properties...
    Monday, October 31, 2011 11:27 PM
  • Hi Selvakumar,

    Thank you for your post.

    According to your description, I understand you want when user Scroll any one datagrid the another datagrid also should automatically scroll with that same position.

    What Johnny and Matt said is correct. Have you resolved your issue? 

    Also,please check out below link about Scroll Synchronization for your reference:

    http://www.codeproject.com/KB/WPF/ScrollSynchronization.aspx

    If you have any additional questions, please feel free to let me know.

    Have a nice day. 

     


    Annabella Luo [MSFT]
    MSDN Community Support | Feedback to us
    Get or Request Code Sample from Microsoft
    Please remember to mark the replies as answers if they help and unmark them if they provide no help.


    Wednesday, November 02, 2011 3:05 AM
  • We are temporarily marking this as "Answer", if you have any concerns or new findings; please feel free to unmark this.

    Best regards.


    Annabella Luo [MSFT]
    MSDN Community Support | Feedback to us
    Get or Request Code Sample from Microsoft
    Please remember to mark the replies as answers if they help and unmark them if they provide no help.

    Monday, November 07, 2011 1:38 AM