Liaison WPF Datagrid ne met pas à jour avant de cliquer sur l'en-tête de ligne
J'ai un datagrid qui est lié à une Liste dans le modèle de vue. La grille du contenu n'est pas mis à jour jusqu'à ce que je clique sur l'en-tête de ligne. En cliquant dans diverses cellules n'est pas l'affecter. Je dois cliquer sur l'en-tête.
C'est la grille de données dans le code XAML:
<DataGrid x:Name="TransactionDetailsGrid" Grid.Row="1" AutoGenerateColumns="False" SelectionMode="Extended" IsReadOnly="True" HeadersVisibility="Column"
ItemsSource="{Binding TransactionDetailList}" SelectedItem="{Binding SelectedTransactionDetail}" GridLinesVisibility="None">
<DataGrid.Columns>
<DataGridTextColumn Binding="{Binding Path=Account.AccountNumber}" Header="Account No." HeaderStyle="{StaticResource DataGridHeaderStyleCenter}" Width="120" />
<DataGridTextColumn Binding="{Binding Path=Account.AccountName}" Header="Account Name" HeaderStyle="{StaticResource DataGridHeaderStyleCenter}" Width="*" />
<DataGridTextColumn Binding="{Binding Path=Amount}" Header="Amount" HeaderStyle="{StaticResource DataGridHeaderStyleCenter}" Width="120" />
</DataGrid.Columns>
</DataGrid>
Et c'est à partir de la vue modèle:
public List<TransactionDetail> TransactionDetailList
{
get { return this._transactionDetailList; }
set
{
this._transactionDetailList = value;
RaisePropertyChanged("TransactionDetailList");
}
}
C'est la modification de l'un des éléments, dans le modèle de vue:
private void AddTransactionDetail()
{
TransactionDetailViewModel viewModel = new TransactionDetailViewModel();
MainWindowViewModel.ViewLoader.ShowDialog(viewModel);
if (viewModel.TransactionDetail != null)
{
this.TransactionDetailList.Add(viewModel.TransactionDetail);
RaisePropertyChanged("TransactionDetailList");
}
}
Après cela fonctionne, je peux mettre un point d'arrêt sur la lecture de TransactionDetailList, et la collection a l'élément en elle. Cependant, la grille de données est vide. Si je clique sur la ligne d'en-tête, l'élément apparaît dans la grille.
J'ai le même problème quand on fait une modification.
Je l'ai fait avec succès avant, donc je ne suis pas sûr de ce qui est différent d'ici. Ai-je raté quelque chose d'évident? Pourquoi ne pas la grille afficher son contenu jusqu'à ce que je clique sur la ligne d'en-tête?
Je viens de remarquer quelque chose d'intéressant. Quand je clique sur l'en-tête de grille, le point d'arrêt dans le TransactionDetailList de lecture n'est pas touché, mais les données sont encore présente. Donc, c'est comme la grille a l'info, c'est juste de ne pas le montrer jusqu'à l'en-tête est cliqué.
Après le passage à l'utilisation ObservableCollection, il a travaillé. Mais maintenant, je vais avoir le même problème avec la modification (grille n'est pas mis à jour jusqu'en cliquant sur l'en-tête):
private void EditTransactionDetail()
{
TransactionDetailViewModel viewModel = new TransactionDetailViewModel(this.SelectedTransactionDetail);
MainWindowViewModel.ViewLoader.ShowDialog(new TransactionDetailViewModel(this.SelectedTransactionDetail));
RaisePropertyChanged("TransactionDetailList");
}
Mon entité doivent implémenter INotifyPropertyChanged? Si je change la collection, et l'appel RaisePropertyChanged, ne pourrait-il pas de provoquer une mise à jour de la grille?
source d'informationauteur Bob Horn
Vous devez vous connecter pour publier un commentaire.
Le problème est que lorsque vous ajoutez ou supprimez un élément de la collection, le setter n'est pas appelé. Cela signifie
INotifyPropertyChanged
n'est pas appelé, et la vue n'a aucun moyen de le savoir doit être actualisé.WPF résout ce problème en soutenant la
INotifyCollectionChanged
interface.Essayez d'utiliser un
ObservableCollection<TransactionDetail>
au lieu d'unList<TransactionDetail>
.ObservableCollection<T>
est construit dans, et met en œuvreINotifyCollectionChanged
de sorte que vous n'aurez pas à faire beaucoup pour votre code.Assurez-vous également de poursuivre la mise en œuvre
INotifyPropertyChanged
sur votre modèle de vue que vous avez déjà. De cette façon, l'avis sera notifié lorsque vous remplacez l'ensemble de la collection (lorsque le setter est appelé).Voir:
Modifier:
Aussi, vous devez mettre en œuvre
INotifyPropertyChanged
surTransactionDetail
trop. Si vous ne pouvez pas, l'envelopper dans une classe qui implémenteINotifyPropertyChanged
.Si vous n'avez pas la mettre en œuvre sur
TransactionDetail
que les modifications que vous apportez qui n'a pas d'impact sur la liste, mais ne les propriétés d'impact sur unTransactionDetail
exemple, de ne pas s'afficher dans l'INTERFACE utilisateur jusqu'à ce que vous en quelque sorte d'actualisation de l'ensemble de la liste.Si vous avez essayé de résoudre ce problème en appelant
RaisePropertyChanged
sur la liste des biens, alors votre INTERFACE utilisateur pense à l'ensemble de la liste (et donc de l'ensemble des objets de l'INTERFACE utilisateur) doit être jeté dehors, et mis à jour. Cela va tuer votre performance et de rendre votre application lent.Si vous le souhaitez, vous de la grille de mise à jour du moment où vous changez l'interface IEnumerable liste, il est lié à, en faire un type de liste qui implémente INotifyCollectionChanged. Construit dans le type de données qui a c'est le ObservableCollection (ici aussi). Donc, si vous faites votre propriété ressembler à ceci:
votre grille sera automatiquement ramasser tous les éléments que vous ajoutez ou supprimez de la liste.
Effectivement ce que vous faites ici, c'est la notification lorsque le liste a changé (c'est à dire la liste de référence), mais vous n'êtes pas notifier lors de la contenu de la liste ont changé.