Problem with row virtualization in DataGrid

There is currently a DataGridrelated DataTable. It also has a template column with CheckBoxin it, which we add programmatically. This goal of this column is to track multiple selections in DataGrid.

A factory is used to create CheckBoxes for each row.

There are quite a few entries, so string virtualization is set to true for acceptable performance. However, we see a strange problem, if we check some CheckBoxes in the first 10 lines and then scroll down about 50 lines (the grid has about 10 lines visible at any given time), there are a bunch of other CheckBoxes that seem to be checked randomly .

If you disable row virtualization, this problem does not exist (but the performance is terrible). Is there any way around this? Does anyone know what we can do wrong?

+24
source share
3 answers

If you are looking for speed, ListView Gridview is much faster (and has fewer features).

Try disabling container recycling.

             <tk:DataGrid x:Name="dataGrid" 
             ItemsSource="{Binding Path=Bookings}" 
             AutoGenerateColumns="False" 
             EnableRowVirtualization="True" 
             EnableColumnVirtualization="True"
             VirtualizingStackPanel.VirtualizationMode="Standard"
             VirtualizingStackPanel.IsVirtualizing="True">
+24
source

If you enable virtualization because the datagrid load time is terrible, then here is the solution:

  • disable virtualization
  • let's assume / call the binding of the data source to the datagrid as "Rows",

    public IEnumerable<Row> Rows {get; set;}
    
  • "Row" IsVisible , ( ).

, , , , , , * , , . , , , , View.Visibility , ViewModel - .. , . () , ( ), .

   private _isVisible = false;

    /// <summary>
    /// is false by default, for performance when loading first time. 
    /// </summary>
    public bool IsVisible
    {
        get { return _isVisible; }
        set
        {
            if (_isVisible == value)
                return;
            _isVisible = value;
            RaisePropertyChanged(() => IsVisible);
        }
    }
  • , datagrid, , , true. , , IsVisible , .

    private void OnGridLoaded(object sender, RoutedEventArgs e)
    {
       //sample bool checks, you might not need them...
       if (firstTimeLoad && !_isDataGridLoaded)
       {
           Task.Factory
               .StartNew(() =>
                {
                    /*first time loading performance tweak*/
                     foreach (var row in _viewModel.Rows)
                        ExeOnUi(() => { row.IsVisible = true; });
    
                     _firstTimeLoad = false;
                 })
       }
    
  • ExeOnUi ( , - , anyControl.Dispatcher.CheckAccess, Microsoft.Practices.ServiceLocator):

    static void ExeOnUi (Action action)
    {
        var srv= ServiceLocator.Current.GetInstance<IDispatchService> ();
        if (srv.CheckAccess ())
            action.Invoke ();
        else
            srv.Invoke (action);
    }
    
+4

UpdateSourceTrigger=PropertyChanged .

<DataGridTemplateColumn Header="Visible">
    <DataGridTemplateColumn.CellTemplate>
        <DataTemplate>
            <CheckBox IsChecked="{Binding IsShown,Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}"/>
        </DataTemplate>
    </DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
+1

All Articles