DataGrid 仅更新显示的行

DataGrid only update rows that are shown

我有一个 DataGrid,其中包含一些名称 - 值对,所述名称 - 值对是从硬件设备轮询的。为了提高性能(轮询循环而不是 UI),我想知道显示了哪些绑定项。

<DataGrid Grid.Row="1" ItemsSource="{Binding ParameterViewSource.View}" 
 AutoGenerateColumns="False" CanUserReorderColumns="False"/>

DataGrid 现在默认虚拟化行。但是对于我的后台轮询循环,我想知道我的 CollectionViewSource 的哪些项目当前在 RowPresenter 中。

该方法应该可以在 MVVM 中实现。

我尝试使用 DataGridRowsPresenter - 和 Children(或更具体的 DataContext),但我无法收到有关更改的通知。有什么简单的方法可以达到我想要的效果吗

private static void GridOnLoaded(object sender, RoutedEventArgs routedEventArgs)
        {
            DataGrid grid = (DataGrid)sender;
            var rowPresenter = grid.FindChildRecursive<DataGridRowsPresenter>();

            var items = rowPresenter.Children.OfType<DataGridRow>()
            .Select(x => x.DataContext);
            //Works but does not get notified about changes to the Children 
            //collection which occure if i resize the Grid, Collapse a 
            //Detail Row and so on
        }

我使用附件 属性 解决了这个问题:

public class DataGridHelper
{
     //I skipped the attached Properties (IsAttached, StartIndex and Count) declarations        


    private static void IsAttachedPropertyChangedCallback(DependencyObject dependencyObject, DependencyPropertyChangedEventArgs args)
    {
        DataGrid grid = (DataGrid)dependencyObject;
        grid.Loaded += GridOnLoaded;
    }

    private static void GridOnLoaded(object sender, EventArgs eventArgs)
    {
        DataGrid grid = (DataGrid)sender;
        ScrollBar scrollBar = grid.FindChildRecursive<ScrollBar>("PART_VerticalScrollBar");

        if (scrollBar != null)
        {
            scrollBar.ValueChanged += (o, args) => SetVisibleItems(grid, scrollBar);

            DependencyPropertyDescriptor descriptor = DependencyPropertyDescriptor.FromProperty(RangeBase.MaximumProperty, typeof (ScrollBar));
            descriptor.AddValueChanged(scrollBar, (o, args) => SetVisibleItems(grid, scrollBar));

            SetVisibleItems(grid, scrollBar);
        }
    }

    private static void SetVisibleItems(DataGrid grid, ScrollBar scrollBar)
    {
        int startIndex = (int)Math.Floor(scrollBar.Value);
        int count = (int)Math.Ceiling(grid.Items.Count - scrollBar.Maximum);

        SetStartIndex(grid, startIndex);
        SetCount(grid, count);
    }

然后使用 OneWayToSource 将我的 DataGrid 的附加属性绑定到某些视图模型属性。

 <DataGrid Grid.Row="1" ItemsSource="{Binding ParameterViewSource.View}" AutoGenerateColumns="False" CanUserReorderColumns="False"
                  userInterface:DataGridHelper.IsAttached="True"
                  userInterface:DataGridHelper.Count="{Binding Path=Count, Mode=OneWayToSource}"
                  userInterface:DataGridHelper.StartIndex="{Binding Path=StartIndex, Mode=OneWayToSource}">

您还可以处理 DataGrid 上的 Count 和 StartIndex 并提取 Items 的 SubArray 属性。