Check visible rows in a WPF DataGrid

后端 未结 4 914
伪装坚强ぢ
伪装坚强ぢ 2020-12-19 05:53

I have a WPF DataGrid, which when there are too many rows to view on the screen it gets a vertical scrollbar. What I would like to know is if there is a way to

相关标签:
4条回答
  • 2020-12-19 05:58

    Using the following method worked for me:

    // mHorizontalScrollBar is the HorizontalScrollBar subclass control's instance
    
    // Get the total item count
    nTotalCount = DataGrid1.Items.Count; 
    
    // Get the first visible row index 
    nFirstVisibleRow = mHorizontalScrollBar.Value;
    
    // Get the last visible row index
    nLastVisibleRow = nFirstVisibleRow + nTotalCount - mHorizontalScrollBar.Maximum;
    
    0 讨论(0)
  • Detecting scrolling is as easy as

    <DataGrid ScrollViewer.ScrollChanged="DataGrid_ScrollChanged" />
    

    Now you must get ScrollViewer instance:

    void DataGrid_ScrollChanged(object sender, RoutedEventArgs e)
    {
        var scroll = FindVisualChild<ScrollViewer>((DependencyObject)sender);
        ...
    }
    

    (Not sure where is origin of FindVisualChild, but there are plenty of implementations, e.g. here)

    And then you can

    int firstRow = (int)scroll.VerticalOffset;
    int lastRow = (int)scroll.VerticalOffset + (int)scroll.ViewportHeight + 1;
    
    0 讨论(0)
  • 2020-12-19 06:06

    It's sort of an overcomplicated way of doing it, but it may work. First, subclass DataGridRowsPresenter and override the OnViewportOffsetChanged method. Then, duplicate the standard control template for the datagrid, and replace the DataGridRowsPresenter with your own. I leave the details of hit testing for a row relative to the viewport up to you ;-).

    What are you trying to accomplish, specifically? Maybe we can come up with a better way, as this may be very brittle and requires a bunch of extra work (i.e. keeping the control template in sync if they update it).

    0 讨论(0)
  • 2020-12-19 06:14

    How about subscribing to the ScrollViewer.ScrollChanged event on the DataGrid's ScrollViewer? The event arguments for it are pretty extensive, describing how much the ScrollViewer moved and what its new Vertical offset is. Also, according to MSDN:

    If CanContentScroll is true, the values of the ExtentHeight, ScrollableHeight, ViewportHeight, and VerticalOffset properties are number of items. If CanContentScroll is false, the values of these properties are Device Independent Pixels.

    CanContentScroll is indeed the case for the ScrollViewer for a DataGrid.

    All you have to do is find the ScrollViewer:

    ScrollViewer scrollview = FindVisualChild<ScrollViewer>(dataGrid);
    

    using an implementation of FindVisualChild that can be found in various places (like here: Finding control within WPF itemscontrol).

    0 讨论(0)
提交回复
热议问题