Ho un DataGrid hacked-insieme con file gruppo totali parziali in uno dei miei progetti. Non eravamo preoccupati di alcuni dei problemi che hai sollevato, come nascondere e ordinare le colonne, quindi non so con certezza se può essere esteso per quello. Mi rendo anche conto che potrebbero esserci problemi di prestazioni che potrebbero essere un problema con grandi set (la mia finestra sta funzionando 32 DataGrids separati - ahi) Ma è una direzione diversa dalle altre soluzioni che ho visto, quindi ho pensato di buttarlo qui e vedere se ti aiuta.
My soluzione consiste di 2 componenti principali:
1. Le righe del totale parziale non sono righe nel DataGrid principale, ma sono DataGrid separati. In realtà, ho due griglie in più in ogni gruppo: 1 nell'intestazione che viene visualizzata solo quando il gruppo è collassato e uno al di sotto di ItemsPresenter. L'oggetto ItemsSource per il subtotale DataGrid proviene da un convertitore che prende gli elementi nel gruppo e restituisce un modello di vista aggregato.Le colonne delle griglie subtotali sono esattamente uguali alla griglia principale (compilate in DataGrid_Loaded, anche se sono sicuro che potrebbe essere fatto anche in xaml).
<GroupStyle>
<GroupStyle.ContainerStyle>
<Style TargetType="{x:Type GroupItem}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type GroupItem}">
<Expander Background="Gray" HorizontalAlignment="Left" IsExpanded="True"
ScrollViewer.CanContentScroll="True">
<Expander.Header>
<DataGrid Name="HeaderGrid" ItemsSource="{Binding Path=., Converter={StaticResource SumConverter}}"
Loaded="DataGrid_Loaded" HeadersVisibility="Row"
Margin="25 0 0 0" PreviewMouseDown="HeaderGrid_PreviewMouseDown">
<DataGrid.Style>
<Style TargetType="DataGrid">
<Style.Triggers>
<DataTrigger Binding="{Binding RelativeSource={RelativeSource AncestorType=Expander}, Path=IsExpanded}"
Value="True">
<Setter Property="Visibility" Value="Collapsed"/>
</DataTrigger>
</Style.Triggers>
</Style>
</DataGrid.Style>
</DataGrid>
</Expander.Header>
<StackPanel>
<ItemsPresenter/>
<DataGrid Name="FooterGrid" ItemsSource="{Binding ElementName=HeaderGrid, Path=ItemsSource, Mode=OneWay}"
Loaded="DataGrid_Loaded" HeadersVisibility="Row"
Margin="50 0 0 0">
<DataGrid.Style>
<Style TargetType="DataGrid">
<Style.Triggers>
<DataTrigger Binding="{Binding RelativeSource={RelativeSource AncestorType=Expander}, Path=IsExpanded}"
Value="False">
<Setter Property="Visibility" Value="Collapsed"/>
</DataTrigger>
</Style.Triggers>
</Style>
</DataGrid>
</StackPanel>
</Expander>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</GroupStyle.ContainerStyle>
</GroupStyle>
2. Quindi il problema è come ottenere tutti i DataGrid si comportino come se fossero una sola griglia. Ho gestito questo sottoclasse DataGridTextColumn
(abbiamo solo testo in questo caso, ma anche altri tipi di colonna dovrebbero funzionare) in una classe chiamata DataGridSharedSizeTextColumn
che simula il comportamento SharedSizeGroup della classe Grid. Ha una proprietà di dipendenza da stringa con un nome di gruppo e tiene traccia di tutte le colonne nello stesso gruppo. Quando si modifica in una colonna, aggiorno il MinWidth in tutte le altre colonne e impone un aggiornamento con DataGridOwner.UpdateLayout()
. Questa classe copre anche il riordino delle colonne e fa un aggiornamento a livello di gruppo ogni volta che DisplayIndex cambia. Penserei che questo metodo funzionerebbe anche con qualsiasi altra proprietà di colonna finché ha un setter.
C'erano altre cose fastidiose da risolvere con selezione, copia, ecc. Ma si è rivelato piuttosto semplice da gestire con gli eventi MouseEntered e MouseLeave e utilizzando un comando Copia personalizzato.
Hai trovato modi per rispondere a queste esigenze? Ecco la mia domanda SO (che ho contrassegnato come duplicata): https://stackoverflow.com/questions/46206673/wpf-datagrid-grouping-and-totals – Simon