Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

WPF DataGrid inside a ScrollViewer

I have a StackPanel with a header control and a DataGrid Inside a Scrollviewer; like so:

<ScrollViewer>
    <StackPanel Orientation="Vertical">
        <Canvas x:Name="header" 
                Height="300" />
        <DataGrid x:Name="dataGrid">
        </DataGrid>
    </StackPanel>
</ScrollViewer>

The scoll behavior should fulfill these requirements:

  • Scrolling while MouseOver the DataGrid should scroll the outer ScrollViewer
  • The header control (symbolized by Canvas) is scrolled by the ScollViewer.

  • The horizontal scrollbar at the bottom of the DataGrid should be preserved on screen at any time.

  • The horizontal scrollbar should not scroll the header control, only the DataGrid.

I tried various settings for the DataGrid.ScrollViewer but none have the desired effect, nor does changing the StackPanel to a WrapPanel or even Grid help any.

Is this possible? Any help and resources to read are appreciated.

like image 387
Prophet Lamb Avatar asked Oct 21 '25 08:10

Prophet Lamb


1 Answers

I've been struggling with your first problem for some time as well - having an inner ScrollViewer (or DataGrid in this case) scroll the outer ScrollViewer. But I think I have a pretty elegant solution. You have to add an event handler to the PreviewMouseWheel event of the DataGrid (and a name to the ScrollViewer):

<ScrollViewer x:Name="scroll_viewer">
    <StackPanel Orientation="Vertical">
        <Canvas x:Name="header" 
                Height="300" />
        <DataGrid x:Name="dataGrid" PreviewMouseWheel="mousewheel">
        </DataGrid>
    </StackPanel>
</ScrollViewer>

Then the event handling method:

private void mousewheel(object sender, MouseWheelEventArgs e)
{
    //what we're doing here, is that we're invoking the "MouseWheel" event of the parent ScrollViewer.

    //first, we make the object with the event arguments (using the values from the current event)
    var args = new MouseWheelEventArgs(e.MouseDevice, e.Timestamp, e.Delta);

    //then we need to set the event that we're invoking.
    //the ScrollViewer control internally does the scrolling on MouseWheelEvent, so that's what we're going to use:
    args.RoutedEvent = ScrollViewer.MouseWheelEvent;

    //and finally, we raise the event on the parent ScrollViewer.
    scroll_viewer.RaiseEvent(args);
}

Hope this helps!

like image 175
vidmartin Avatar answered Oct 22 '25 23:10

vidmartin



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!