Ho un ItemsControl in XAML dove sto visualizzando un expander per ogni gruppo in modo da poter espandere/comprimere il gruppo. Voglio mantenere lo stato della proprietà IsExpanded
(e potenzialmente altre impostazioni relative alla visualizzazione dell'intestazione del gruppo). Normalmente hai solo una classe con le proprietà su di essa e ti leghi a questo. Tuttavia, il contesto dati per il gruppo è CollectionViewGroup
. Ora questa classe non è molto utile in quanto ti dà solo la proprietà Name e gli elementi nel gruppo (che va bene se vuoi solo un'intestazione e magari visualizzare una sorta di metrica in base al numero di elementi nel gruppo o alla loro contenuto ma non se vuoi solo memorizzare dati personalizzati sullo stato dell'intestazione dell'interfaccia di gruppo). Quello che mi piacerebbe fare è derivare da questa classe e aggiungere altre proprietà alla mia classe derivata e associarla a quella. Ma non sembra essere un modo semplice per farlo. Tutti i dettagli della generazione di gruppo sembrano essere nascosti nelle classi interne, il che è molto frustrante. Qualcuno ha seguito il percorso di implementazione di ICollectionView
(e quindi presumibilmente tutte le altre classi correlate)? Sembra un enorme lavoro replicare tutto in ListCollectionView
solo per poter creare una classe personalizzata CollectionViewGroup
e collegarla a quella! Grazie.Come associare dati personalizzati a CollectionViewGroup?
risposta
Un approccio semplice sarebbe quello di avvolgere il CollectionViewGroup in un'altra classe ViewModel che fornisce le proprietà di visualizzazione aggiuntive necessarie come IsExpanded. Una lezione che ho imparato a mio modo non era quella di piegare xaml/view in modo che corrispondesse ai dati aziendali. Piuttosto piegare/avvolgere o convertire i dati aziendali per soddisfare i requisiti dell'interfaccia utente.
Un approccio consiste nell'utilizzare uno MultiBinding
per trovare o calcolare i dati personalizzati e il bind-time.
Ho fatto un DataGrid
con gruppi che mostra nell'intestazione somma delle voci valore specifico nel gruppo, per aggiornare questa somma quando Articoli gruppo modifiche ho fatto un multivalore vincolante con un convertitore più valori, la rilegatura il multivalore con ItemCount
la proprietà consente di ricevere una notifica quando le voci del gruppo cambiano e quindi di aggiornare la somma e visualizzare il valore del newsum.
Ecco il codice per la classe convertitore multivalore:
Public Class UserBalanceConverter
Implements IMultiValueConverter
Private Function GetSubTotal(ByVal obj As CollectionViewGroup) As String
Dim total As Decimal
For Each objItem As Object In obj.Items
If TypeOf objItem Is Account Then
Dim a As Account = DirectCast(objItem, Account)
Dim rate As Decimal = 1
rate = 1/ExchangeRatesInfo.GetExchangeRate(a.currencyCode.ToString)
total += a.Balance * rate
Else
total += GetSubTotal(objItem)
End If
Next
Return total.ToString("C")
End Function
Public Function Convert(ByVal value() As Object,
ByVal targetType As System.Type,
ByVal parameter As Object,
ByVal culture As System.Globalization.CultureInfo) _
As Object Implements System.Windows.Data.IMultiValueConverter.Convert
Dim cvg As CollectionViewGroup = CType(value(1), CollectionViewGroup)
Return GetSubTotal(cvg)
End Function
Public Function ConvertBack(ByVal value As Object,
ByVal targetType() As System.Type,
ByVal parameter As Object,
ByVal culture As System.Globalization.CultureInfo) _
As Object() Implements System.Windows.Data.IMultiValueConverter.ConvertBack
Throw New NotImplementedException
End Function
End Class
Poi in XAML si utilizza il convertitore multivalore in uno stile utilizzato per GroupItem:
<Style TargetType ="{x:Type GroupItem}" x:Key="UserGroupHeaderStyle">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type GroupItem}">
<Expander x:Name="exp" IsExpanded="False">
<Expander.Header>
<StackPanel >
<TextBlock Text="{Binding Name}" />
<StackPanel Orientation="Horizontal" >
<TextBlock Text="{Binding ItemCount}">
<TextBlock Text=" "/>
<TextBlock Text="items" />
<TextBlock Text=" "/>
<TextBlock Text="Balance: " />
<TextBlock>
<TextBlock.Text>
<MultiBinding Converter="{StaticResource UserBalanceConverter}">
<Binding Path="ItemCount"/>
<Binding />
</MultiBinding>
</TextBlock.Text>
</TextBlock>
</StackPanel>
</StackPanel>
</Expander.Header>
<ItemsPresenter />
</Expander>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
Finitura con l'applicazione lo stile al vostro DataGrid:
<DataGrid.GroupStyle>
<GroupStyle ContainerStyle="{StaticResource UserGroupHeaderStyle}">
<GroupStyle.Panel>
<ItemsPanelTemplate>
<DataGridRowsPresenter/>
</ItemsPanelTemplate>
</GroupStyle.Panel>
</GroupStyle>
</DataGrid.GroupStyle>
Inoltre, non dimenticare di dichiarare la classe di conversione i n la sezione risorse del tuo XAML:
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<local:UserBalanceConverter x:Key="UserBalanceConverter"/>
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
Et Voilà! Esso funziona magicamente!
HTH
come risponde la domanda degli OP? ha chiesto come mantenere il valore IsExpanded e non generare metriche dagli elementi che ha escluso nella domanda. – Firo
sono stato in grado di risolvere esattamente questo problema (vale a dire il legame con IsExpanded
) utilizzando un approccio che è in qualche modo simile al suggerimento di Cédric, ma in un modo apparentemente più MVVM:
<ControlTemplate TargetType="GroupItem">
<TreeViewItem IsExpanded="{Binding Items[0].IsGroupExpanded, Mode=TwoWay}">
<TreeViewItem.Header>
<TextBlock Text="{Binding Name}" />
</TreeViewItem.Header>
<TreeViewItem.Items>
<ItemsPresenter />
</TreeViewItem.Items>
</TreeViewItem>
</ControlTemplate>
Entrambi i parametri ItemViewModel.IsGroupExpanded
setter e getter reindirizzano a Group.IsExpanded
.
Si noti che è necessario specificare Mode=TwoWay
, poiché sembra legato OneWay
per impostazione predefinita.
- 1. Come associare eventi personalizzati in AngularJS?
- 2. Come associare dati .resizable(). Draggable()?
- 3. Come associare dati gerarchici a un TreeView WPF?
- 4. Come associare i dati LINQ all'elenco a discesa
- 5. Qt - Come associare i dati con QTableWidgetItem?
- 6. Come associare dati - un attributo src iframe?
- 7. dati personalizzati Elmah YSOD
- 8. Dati principali personalizzati SectionNameKeyPath
- 9. Come associare il valore selezionato a DropDownList
- 10. come visualizzare i dati personalizzati da tipi di post personalizzati
- 11. Come associare Dataset a DataGridView nell'applicazione Windows
- 12. Google Maps API V3: Come aggiungere dati personalizzati ai marcatori
- 13. Come associare QModelIndex a una nuova riga?
- 14. È possibile associare i dati a un controllo TreeView?
- 15. È possibile associare dati a un metodo in Silverlight?
- 16. Come associare correttamente xml a DataGrid WPF?
- 17. Posso associare moduli a un archivio dati Dojo?
- 18. Associare un numero elevato di dati a una casella combinata?
- 19. Dati personalizzati in jQuery ordinabili?
- 20. Come associare il pulsante a ListView.SelectedItem
- 21. Provider di dati .NET personalizzati
- 22. Associare eventi personalizzati di animazione CSS personalizzati con jQuery o JavaScript?
- 23. Tipi di dati personalizzati SQLITE?
- 24. Come associare un controllo a discesa a un'origine dati in ASP.NET
- 25. Accesso membri di un tipo di dati personalizzati a Haskell
- 26. Tipo di dati personalizzati Doctrine
- 27. come associare più parametri a richiesta MySQLi
- 28. Come associare eventi jquery a mio avviso
- 29. Come associare un socket a più interfacce
- 30. Come associare il layout a più qualificazioni
Puoi spiegare il tuo punto con un esempio? –