XAML WPF DataGrid似乎未虚拟化行

wljmcqd8  于 2022-12-07  发布在  其他
关注(0)|答案(1)|浏览(184)

I'm working on a application where the bulk of my content is presented to users with the built in WPFDataGrid . Here is what my DataGrid looks like. I don't set anything but the RowDefinitions on the parent Grid .

<UserControl xmlns="blah blah blah">
  <Grid>
    <Grid.RowDefinitions>
      <RowDefinition />
      <RowDefinition Height="Auto"/>
     </Grid.RowDefinitions>

  <DataGrid x:Name="dgrMaterialCollection" 
          IsReadOnly="True" 
          ItemsSource="{Binding Path=MyObservableCollection, UpdateSourceTrigger=PropertyChanged}" 
          AutoGenerateColumns="True" 
          AutoGeneratingColumn="dgrMaterialCollection_AutoGeneratingColumn"
          AutoGeneratedColumns="dgrMaterialCollection_AutoGeneratedColumns"
          CanUserResizeColumns="True" 
          CanUserReorderColumns="True"
          CanUserSortColumns="True"
          EnableRowVirtualization="True"
          EnableColumnVirtualization="True"
          VirtualizingPanel.IsVirtualizingWhenGrouping="True"
          VirtualizingPanel.VirtualizationMode="Standard"
          VirtualizingPanel.IsVirtualizing="True"
          SelectionMode="Single"
          SelectionUnit="FullRow"
          ScrollViewer.CanContentScroll="False"
          RowHeaderWidth="0" 
          Grid.Row="0"
          RowHeight="32"
          RowDetailsVisibilityMode="Collapsed">
  <DataGrid.Resources>
    <ResourceDictionary>
      <ResourceDictionary.MergedDictionaries>
        <ResourceDictionary Source="DataGridStyle.xaml"/>
      </ResourceDictionary.MergedDictionaries>

      <!-- A few value converters -->
     </ResourceDictionary>
   </DataGrid.Resources>
   <!-- Some Manually Declared Columns -->
  </DataGrid>
  <StackPanel Grid.Row="1">
    <SomeTextBoxes/>
  </StackPanel>
 </Grid>
</UserControl>

When my application displays the DataGrid , there is about a 10 - 20 second delay depending the size of the dataset. During this delay the UI is locked up. Once the data grid is loaded - I can scroll through all few thousand items without any delay. When I say without delay, I mean clicking on the scroll bar and moving it up and down as fast as humanly possible, with no delay in rendering the rows as it scrolls. It seems like the virtualization is not working, and instead the datagrid is creating all the rows at one time instead of while the user is scrolling.
My Datagrid is nested in the following structure (spread out over multiple xaml files). There are no extra ScrollViewers , StackPanels , or anything. Just this.

<RibbonWindow>
  <Grid>
    <ContentControl> <!-- Populated via a DataTemplate and ContentTemplateSelector -->
      <UserControl>
        <UserControl>
          <UserControl>
            <Grid>
              <Here is the DataGrid>

Some things I have attempted to speed up the loading

  • Explicitly set all the column widths (shaved about 10 second off my load time)
  • Turned off AutoGenerateColumns (didn't make a difference).
  • Disabling the styles set in the DataGrid'sRessourceDictionary (no difference)
  • Load items into my ObservableCollection on a background thread, using async/await, and other multithreaded strategies. This has made no difference in load times.
  • Add items to a new ObservableCollection , then setting it to the databound property (so the events aren't triggered)
  • Add items to the ObservableCollection one at a time (events are triggered upon each add)
  • Turning virtualization on and off makes no difference in load time.

I know the delay is not caused by populating the ObservableCollection . It starts after the collection is fully populated, and when the WPFDataGrid is rendering all the rows/columns. I have virtualization enabled and it still takes forever. I am using the .NET framework 4.5.1 (so the 4.6 issue with Virtualization is not causing this). There are also long delays when sorting (using built in datagrid sorting) and resizing columns from the UI.
What am I missing here? Is there something I can do to ensure Virtualization is working? What are some things that might speed this up? If I know Virtualization is working then I may move onto a new strategy, like paging or some kind of lazy loading. Another solution I would be willing to work with is one where the user interface is not blocked/frozen while all the rows are being rendered. That way the users could at least click around on other thing while rows are added in.

hlswsv35

hlswsv351#

DataGrid元素的ScrollViewer.CanContentScroll值必须设定为True,数据列虚拟化才能正常运作。Here is an explanation说明为何必须如此设定。
感谢ChrisW在这个问题的评论中抓住了这一点。

相关问题