2010-06-15 7 views
5

Pourquoi l'événement collectionchanged ne se déclenche-t-il pas dans le code suivant, mais je peux voir la nouvelle instance d'InventoryBTO que j'ajoute à ObservableCollection?ObservableCollection et CollectionChanged Evénement

private ObservableCollection<InventoryBTO> _inventoryRecords; 
    public ObservableCollection<InventoryBTO> InventoryRecords 
    { 
     get { return _inventoryRecords; } 
     set { _inventoryRecords = value; } 
    } 

    private InventoryBTO _selectedRecord; 
    public InventoryBTO SelectedRecord 
    { 
     get { return _selectedRecord; } 
     set 
     { 
      if (_selectedRecord != value) 
      { 
       _selectedRecord = value; 
       OnPropertyChanged(new PropertyChangedEventArgs("SelectedRecord")); 
      } 
     } 
    } 

    public InventoryViewModel() 
    { 
     if (_inventoryRecords == null) 
     { 
      InventoryRecords = new ObservableCollection<InventoryBTO>(); 
      this.InventoryRecords.CollectionChanged += new NotifyCollectionChangedEventHandler(InventoryRecords_CollectionChanged); 
     } 

     _inventoryRecords = InventoryListBTO.GetAllInventoryRecords(); 
    } 

    void InventoryRecords_CollectionChanged(object sender, NotifyCollectionChangedEventArgs e) 
    { 

    } 
+1

ressemble à vous accrocher à la collection dans votre cteur puis immédiatement écraser la référence avec une collection totalement différente. Peut-être que vous vouliez plutôt faire un AddRange au lieu d'écraser? Quoi qu'il en soit, la collection observable que vous avez créée puis connectée est –

Répondre

10

Le problème est que vous affectez votre membre privé à une nouvelle instance d'un ObservableCollection que vous récupérez de votre méthode. Par conséquent, ce qui se passe est que vous vous connectez à l'événement d'une collection, mais que vous perdez cette instance et la remplacez par une nouvelle instance à laquelle vous n'avez jamais connecté un gestionnaire d'événements. Voici ce que vous pouvez faire. Créer une classe qui hérite de ObservableCollection et ajoute une méthode AddRange:

public class RangeObservableCollection<T> : ObservableCollection<T> 
{ 
    private bool surpressEvents = false; 

    public void AddRange(IEnumerable<T> items) 
    { 
     surpressEvents = true; 
     foreach (var item in items) 
     { 
      base.Add(item); 
     } 
     this.surpressEvents = false; 
     this.OnCollectionChanged(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Add, items.ToList())); 

    } 

    protected override void OnCollectionChanged(System.Collections.Specialized.NotifyCollectionChangedEventArgs e) 
    { 
     if (!this.surpressEvents) 
     { 
      base.OnCollectionChanged(e); 
     } 
    } 
} 

Ensuite, vous pouvez changer votre classe à ceci:

private RangeObservableCollection<InventoryBTO> _inventoryRecords; 
public RangeObservableCollection<InventoryBTO> InventoryRecords 
{ 
    get { return _inventoryRecords; } 
    set { _inventoryRecords = value; } 
} 

private InventoryBTO _selectedRecord; 
public InventoryBTO SelectedRecord 
{ 
    get { return _selectedRecord; } 
    set 
    { 
     if (_selectedRecord != value) 
     { 
      _selectedRecord = value; 
      OnPropertyChanged(new PropertyChangedEventArgs("SelectedRecord")); 
     } 
    } 
} 

public InventoryViewModel() 
{ 
    if (_inventoryRecords == null) 
    { 
     InventoryRecords = new ObservableCollection<InventoryBTO>(); 
     this.InventoryRecords.CollectionChanged += new NotifyCollectionChangedEventHandler(InventoryRecords_CollectionChanged); 
    } 

    this.InventoryRecords.AddRange(InventoryListBTO.GetAllInventoryRecords()); 
} 

void InventoryRecords_CollectionChanged(object sender, NotifyCollectionChangedEventArgs e) 
{ 
    //e.NewItems will be an IList of all the items that were added in the AddRange method... 
} 
+0

La première ligne pointait sur mon problème. J'ai donc ajouté le gestionnaire d'événements CollectionChanged sur le setter de la propriété. –

0

Essayez cette

public ObservableCollection<InventoryBTO> InventoryRecords 
{ 
    get { return _inventoryRecords; } 
    set 
    { 
     _inventoryRecords = value; 
     onPropertyChanged(this, "InventoryRecords"); 

    } 
} 

OU

public ObservableCollection<InventoryBTO> InventoryRecords 
{ 
    get { return _inventoryRecords; } 
    set 
    { 
     _inventoryRecords = value; 
     OnPropertyChanged(new PropertyChangedEventArgs("InventoryRecords")); 

    } 
} 

En fonction de votre mise en œuvre.

+0

depuis longtemps, chaque fois qu'une valeur est définie sur une propriété, la méthode "onPropertyChanged" est appelée, ce qui déclenche à son tour l'événement PropertyChanged. – VoodooChild

+0

Je ne comprends pas. Comment l'événement PropertyChanged affecte l'événement CollectionChanged de la collection lors de l'ajout d'un nouvel InventoryBTO? – user337816

+0

De même, comment accéderiez-vous aux propriétés de l'événement modifié de la collection contenant les nouveaux éléments ajoutés. – user337816