2 votes

Traitement Vérifié différemment selon qu'il est appelé à partir d'un clic de souris ou de la virtualisation.

J'ai une grille de données WPF toolkit avec la virtualisation activée. Chaque ligne a une case à cocher liée à un bool dans le modèle sous-jacent.

Les cases à cocher (en plus de la liaison de données) ont également des gestionnaires de cochage et de décochage ( !) pour permettre de cocher plusieurs éléments à la fois si vous avez cliqué sur une case avec plusieurs lignes sélectionnées.

Voici le xaml :

<Controls:DataGrid ItemsSource="{Binding UnderlyingData}"
                   AutoGenerateColumns="False"
                   HeadersVisibility="Column">

  <Controls:DataGrid.Columns>
    <Controls:DataGridTemplateColumn Header="Use?" SortMemberPath="Use">
      <Controls:DataGridTemplateColumn.CellTemplate>
        <DataTemplate>
          <CheckBox Style="{StaticResource DataGridCheckBoxStyle}" IsChecked="{Binding Spike}"
                    Checked="CheckBox_Checked" Unchecked="CheckBox_Unchecked" />
        </DataTemplate>
      </Controls:DataGridTemplateColumn.CellTemplate>
    </Controls:DataGridTemplateColumn>              
  </Controls:DataGrid.Columns>
</Controls:DataGrid>

Et les handlers Checked/Unchecked :

private void CheckBox_Checked(object sender, RoutedEventArgs e)
{
    if (!processingMultipleRows)
    {
        UpdateAllSelected(e.OriginalSource as ToggleButton);
        e.Handled = true;
    }
}

private void CheckBox_Unchecked(object sender, RoutedEventArgs e)
{
    if (!processingMultipleRows)
    {
        UpdateAllSelected(e.OriginalSource as ToggleButton);
        e.Handled = true;
    }
}

private void UpdateAllSelected(ToggleButton checkBox)
{
    processingMultipleRows= true;
    var include = checkBox.IsChecked ?? false;
    tickBoxSelector.ApplyToAllSelected<RowViewModel>(checkBox, p => p.Use = include);
    ViewModel.ProcessUseStateChange();
    processingMultipleRows= false;
}

Ce code fonctionne dans tous les sens sauf un. ViewModel.ProcessUseStateChange() est assez lent et est actuellement appelé une fois chaque fois que vous basculez une ou plusieurs CheckBox. Ce qui est bien, mais il est également appelé une fois pour chaque nouvelle ligne apparaissant dans la vue lorsque vous faites défiler la grille de données, puisque la virtualisation signifie que de nouvelles lignes doivent être créées et que leur état Check doit être défini.

Existe-t-il un moyen astucieux de déterminer si Checked est appelé en réponse à un clic de souris ou à une instanciation d'une nouvelle ligne due à la virtualisation ?

2voto

Jackson Pope Points 9294

La solution que j'ai trouvée en fin de compte a été de gérer l'événement Click, plutôt que Checked/Unchecked, ce qui a simplifié les choses de façon considérable :

<Controls:DataGrid ItemsSource="{Binding UnderlyingData}"
                   AutoGenerateColumns="False"
                   HeadersVisibility="Column">

  <Controls:DataGrid.Columns>
    <Controls:DataGridTemplateColumn Header="Use?" SortMemberPath="Use">
      <Controls:DataGridTemplateColumn.CellTemplate>
        <DataTemplate>
          <CheckBox Style="{StaticResource DataGridCheckBoxStyle}" IsChecked="{Binding Spike}"
                    Click="CheckBox_Clicked"/>
        </DataTemplate>
      </Controls:DataGridTemplateColumn.CellTemplate>
    </Controls:DataGridTemplateColumn>              
  </Controls:DataGrid.Columns>
</Controls:DataGrid>

et :

private void CheckBox_Clicked(object sender, RoutedEventArgs e)
{
    UpdateAllSelected(e.OriginalSource as ToggleButton);
    e.Handled = true;
}

private void UpdateAllSelected(ToggleButton checkBox)
{
    var include = checkBox.IsChecked ?? false;
    tickBoxSelector.ApplyToAllSelected<RowViewModel>(checkBox, p => p.Use = include);
    ViewModel.ProcessUseStateChange();
}

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X