Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

WPF DataGrid: how do I stop auto scrolling when a cell is clicked?

Problem:
If my DataGrid is not entirely visible (horizontal & vertical scrollbars are showing) and I click on one of my cells that is partially visible, the grid auto-scrolls to bring that cell into view. I don't want this to happen. I've tried playing around with RequestBringIntoView, like this:

private void DataGrid_RequestBringIntoView(object sender, RequestBringIntoViewEventArgs e) {     e.Handled = true; } 

But that does nothing.

Things I've tried:

  • My cells are custom UserControls; I tried putting an event handler for RequestBringIntoView on all UserControls that make up my cells, and tried handling the event, thinking that maybe I wasn't doing enough by just handling RequestBringIntoView on the DataGrid itself. This did not work.
  • Hosted the DataGrid inside of a ScrollViewer, and handled the ScrollViewer's RequestBringIntoView event. This actually works, and stops the auto-scrolling behavior, but in my case hosting a DataGrid inside of a ScrollViewer is not at all desirable, so I need to come up with a different solution.

I'm not sure how to stop this behavior, any ideas?

like image 435
Rob Avatar asked Jan 14 '10 14:01

Rob


People also ask

How do I turn off auto scroll in CSS?

This is a Chromium feature recently added, called scroll-anchoring. Disable in the browser: go to chrome://flags/#enable-scroll-anchoring and set "Scroll anchoring" to "Disabled".

What is DataGrid WPF?

A DataGrid is a control that displays data in a customizable grid. It provides a flexible way to display a collection of data in rows and columns. The hierarchical inheritance of DataGrid class is as follows −


2 Answers

Define an EventSetter in the DataGrid.RowStyle to call a handler that prevents the row from being brought into view:

XAML

<DataGrid>     <DataGrid.RowStyle>         <Style TargetType="{x:Type DataGridRow}">               <EventSetter Event="Control.RequestBringIntoView" Handler="DataGrid_Documents_RequestBringIntoView"  />         </Style>     </DataGrid.RowStyle> </DataGrid> 

Handler

private void DataGrid_Documents_RequestBringIntoView(object sender, RequestBringIntoViewEventArgs e) {     e.Handled = true;       } 
like image 118
David Avatar answered Oct 30 '22 18:10

David


I took more time to have a look at this problem as my first solution wasn't working.

However the answer of John is almost the good one. The trick is to catch the RequestBringIntoView event BEFORE it gets to the ScrollViewer in order to mark it has handled.

If you don't have to refine the whole template, you can use the following code:

var scp = TreeHelper.FindVisualChild<ScrollContentPresenter>(this.datagrid); scp.RequestBringIntoView += (s, e) => e.Handled = true; 

We use the ScrollContentPresenter because it's just below the ScrollViewer in the visual tree.

Hope this helps !

like image 20
japf Avatar answered Oct 30 '22 19:10

japf