2012-05-18 8 views
12

Sto implementando un DataGrid WPF che contiene progetti con molte figure chiave. I progetti sono raggruppati per categorie di progetti.come gestire il subtotale di gruppo e ad es. righe di destinazione in WPF DataGrid?

Per ogni categoria ci dovrebbe essere:

  1. una riga che mostra in ogni somma figura colonna chiave di tutte le righe per la colonna.
  2. una riga di destinazione che non fa parte della griglia dell'origine dati in binded to. la riga di destinazione indica per ogni colonna qual è l'obiettivo per l'anno (ad es. quanti soldi ci sono da spendere).

Queste righe devono essere sempre in primo piano in ogni gruppo (filtro di ordinamento).

La mia prima soluzione era quella di avere questi dati nell'intestazione del gruppo. Questa non è una buona soluzione perché l'intestazione di gruppo non supporta le colonne. cioè dovrebbe essere costruito ottenendo le larghezze delle colonne.

Questo potrebbe essere fatto ma diventa complicato quando gli utenti desiderano riordinare e nascondere le colonne.

DataGrid utilizza CollectionViewSource quindi non è popolato con codice C#. Fondamentalmente sto estendere questo esempio: http://msdn.microsoft.com/en-us/library/ff407126.aspx

Grazie & migliori saluti - Matti

+0

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

risposta

0

Una possibilità potrebbe essere quella di aggiungere le righe nella sorgente di dati con valori speciali per il nome e gli altri campi che non hanno senso e utilizzare DataTrigger per mostrarli con colori speciali e forse altri.

Il filtro viene comunque eseguito in C# in modo da non influire su queste righe.

L'ordinamento è l'unico problema qui. Sarebbe così bello solo per dire che alcune righe sono sempre con ordine 0 e con ordine 1 nel gruppo. Ma cause i so come farlo Devo fare l'ordinamento personalizzato in C# per tutte le colonne invece di dichiarare l'ordinamento:

<CollectionViewSource.SortDescriptions> 
    <!-- Requires 'xmlns:scm="clr-namespace:System.ComponentModel;assembly=WindowsBase"' declaration. --> 
    <scm:SortDescription PropertyName="ProjectName"/> 
    <scm:SortDescription PropertyName="Complete" /> 
    <scm:SortDescription PropertyName="DueDate" /> 
</CollectionViewSource.SortDescriptions> 

EDIT: In cima a tutto il resto ha un grave inconveniente a confronto alla mia prima soluzione (somma informazioni nell'intestazione del gruppo) perché durante il filtraggio delle modifiche dovrei aggiornare le somme da calcolare solo per le righe visibili.

Quindi questa risposta è un hack completo e manca tutta l'eleganza e non usa belle caratteristiche che WPF è supponiamo di avere :(

2

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.

+0

mi dispiace non controllare la risposta. spero che aiuti le altre persone. –