2009-11-20 4 views
1

Je n'ai pas implémenté ce modèle depuis un moment (et quand je l'ai fait c'était dans 2, par opposition à 3), et j'ai plusieurs exemples qui semblent tous simples, mais je ne peuvent pas travailler ce que je l'ai fait mal dans le morceau de code ci-dessous (les articles ne sont pas mis à jour lorsque l'événement se déclenche la propriété):Silverlight: INotifyPropertyChanged ne semble pas fonctionner

public partial class Index : Page 
{ 
    private IndexViewModel _vm; 

    public Index() 
    { 
     InitializeComponent(); 
     _vm = new IndexViewModel(19);   

     this.TheDataGrid.ItemsSource = _vm.Rows; 
    } 




public class IndexViewModel : INotifyPropertyChanged 
    { 
    public event PropertyChangedEventHandler PropertyChanged = delegate { }; 

     protected virtual void OnPropertyChanged(PropertyChangedEventArgs e) 
     {   
      this.PropertyChanged(this, e); 
     } 

public SortableCollectionView Rows 
     { 
      get 
     { 
      return _rows; 
     } 
     set 
     { 
      if (_rows == value) 
       return; 

      _rows = value; 
      this.OnPropertyChanged(new PropertyChangedEventArgs("Rows"));         
     } 
    } 

Cela ne rafraîchit pas mon DataGrid ... comme « hack » J'ai dû passer l'objet DataGrid dans mon viewmodel et de se lier là:

public IndexViewModel(int containerModelId, DataGrid shouldNotNeed) 
     { 
      ContainerModelId = containerModelId; 

     LoadOperation<vwColumn> headings = _ttasContext.Load(_ttasContext.GetRecordColumnsQuery(ContainerModelId)); 
     headings.Completed += (sender2, e2) => 
     { 
      //load data 
      LoadOperation<vwDataValue> data = _ttasContext.Load(_ttasContext.GetRecordsQuery(ContainerModelId, null)); 
      data.Completed += (sender3, e3) => 
      { 

        Rows = FormatData(data, headings); 
shouldNotNeed.ItemsSource = Rows; 
       }; 
      }; 
     } 

Répondre

2

_vm.Rows Attribution à TheDataGrid.ItemsSource ne câble aucun rappel de notification de modification automatiquement. Essayez ceci: en XAML:

<... x:Name=TheDataGrid ItemsSource={Binding Rows}> 

Dans le code:

this.DataContext = _vm; 
0

Comme Codism souligne votre problème principal est que vous devez utiliser la liaison pour tirer profit d'un INotifyPropertyChanged. Cependant, je recommande ce modèle de mise en œuvre: -

public event PropertyChangedEventHandler PropertyChanged; 

void NotifyPropertyChanged(string name) 
{   
    if (PropertyChanged != null) 
    PropertyChanged(this, new PropertyChangedEventArgs(name); 
} 

...

set 
    { 
    if (_rows != value) 
    { 
     _rows = value; 
     NotifyPropertyChanged("Rows"); 
    } 
    } 

Notez que cette approche minimise l'impact sur une instance d'objet dont les propriétés ne sont pas respectées. Dans le modèle d'origine, vous créez des instances de PropertyChangedEventArgs et des appels au délégué d'événement, indépendamment du fait que quelque chose écoute ou non.

+0

Je lis dans un autre poste quelque part que si vous aviez le délégué de = {} à la fin de la déclaration que vous ne l'avez pas besoin d'avoir le si (la propriété a changé! = Null) Cependant, même si c'est le cas où vous commentez que le code est moins clair, donc je l'ai changé, merci! –

+0

@Grayson: Oui, il y a un certain avantage à cette astuce delegate {}, mais le modèle normal pour les événements en général est d'utiliser une méthode protégée virtuelle "OnXXXX" qui reçoit l'objet EventArgs approprié. Le problème avec cette approche pour INotifyPropertyChanged est que les valeurs de propriété peuvent changer rapidement (par exemple lors de l'animation). Cela pourrait provoquer la création d'une quantité massive d'instances de PropertyChangedEventArgs mais rien n'écoute, ce qui créerait une charge inutile pour le GC. – AnthonyWJones

0

this.TheDataGrid.ItemsSource = _vm.Rows

Lorsqu'une collection est affecté comme ItemsSource d'un DataGird, toute modification apportée à la collection peuvent être observées par le DataGrid si la source implémente INotifyCollectionChanged .
De votre exemple de code, je ne peux pas dire si le type SortableCollectionView implémente INotifyCollectionChanged ou hérite de ObservableCollection.
L'implémentation de INotifyCollectionChanged signifierait que vous ne pouvez pas réinitialiser le champ de sauvegarde _rows pour les lignes de propriétés, vous pouvez effacer les éléments de la collection et les ajouter si nécessaire.
Hope this helps

Questions connexes