2010-08-19 2 views
0

Greetings, en créant ma première application WPF basée sur MVVM et en essayant de comprendre pourquoi je ne peux pas me connecter à l'événement PropertyChanged d'une propriété de dépendance.Impossible de se connecter à l'événement PropertyChanged à l'aide de MVVM-Light

code dans le modèle de vue parent:

void createClients() 
{ 
    var clients = from client in Repository.GetClients() 
        select new ClientViewModel(Repository, client); 
    foreach (var client in clients) 
    { 
     client.PropertyChanged += onClientPropertyChanged; 
    } 
    Clients = new ViewableCollection<ClientViewModel>(clients); 
    Clients.CollectionChanged += onClientsCollectionChanged; 
} 

// Never gets called 
void onClientPropertyChanged(object sender, PropertyChangedEventArgs e) 
{ 
    if (e.PropertyName == "Name") 
    { 
     //... 
    } 
} 

ViewableCollection est une simple extension de ObservableCollection pour encapsuler une vue.

Dans les ClientViewModel, les setters sont appelés, mais RaisePropertyChanged ne fonctionne pas comme prévu, car onClientPropertyChanged n'est pas appelé. Les deux modèles de vue héritent de ViewModelBase.

public string Name 
{ 
    get { return client.Name; } 
    set 
    { 
     if (value == client.Name) return; 
     client.Name = value; 
     RaisePropertyChanged("Name"); 
    } 
} 

Si câbler jusqu'à PropertyChanged à une méthode dans la ClientViewModel il est tiré, donc je suis perplexe pourquoi cela ne fonctionne pas dans le modèle de vue parent. Où vais-je mal?

+0

Comment déclenchez-vous la modification de la propriété Nom? Si c'est par liaison de données, utilisez-vous le mode TwoWay? Vérifiez la fenêtre de sortie pour les erreurs de liaison de données. En outre, avez-vous essayé de placer un point d'arrêt dans votre setter de propriété Name et est-il en train d'être frappé? –

+0

Salut Matt, oui sur les deux points, mais je viens de trouver une autre question SO qui explique ce comportement. – si618

Répondre

1

This SO question explique le problème; ObservableCollection protège l'événement PropertyChanged.

Une solution consiste à utiliser MVVM Light Messenger:

void createClients() 
{ 
    var clients = from client in Repository.GetClients() 
        select new ClientViewModel(Repository, client); 
    Clients = new ViewableCollection<ClientViewModel>(clients); 
    Clients.CollectionChanged += onClientsCollectionChanged; 
    Messenger.Default.Register<PropertyChangedMessage<string>>(this, (pcm) => 
    { 
     var clientVM = pcm.Sender as ClientViewModel; 
     if (clientVM != null && pcm.PropertyName == "Name") 
     { 
      // ... 
     } 
    }); 
} 

createClients() doit être refactorisé, mais par souci de cohérence avec le code question que je vais le laisser là-dedans. Puis un léger changement à l'accesseur de propriété:

public string Name 
{ 
    get { return client.Name; } 
    set 
    { 
     if (value == client.Name) return; 
     string oldValue = client.Name; 
     client.Name = value; 
     RaisePropertyChanged<string>("Name", oldValue, value, true); 
    } 
} 
+1

-1 car il ne gère pas PropertyChanged sur ObservableCollection. Il parcourt la collection et gère PropertyChanged sur chaque élément. –

+0

Bonjour Matt, je ne vous suis pas? il n'y a pas d'itération, seulement un enregistrement pour recevoir l'événement changé de propriété, et un message diffusé avec la gestion des événements dans le setter de la propriété. Comment gérez-vous cela dans le ObservableCollection s'il protège l'événement PropertyChanged? – si618

+0

D'accord, je n'avais pas réalisé que vous répondiez à votre propre question. Je dois avoir complètement mal compris le problème que vous aviez parce que je ne comprends pas comment c'est lié à votre réponse. SO ne me laissera pas annuler votre réponse à moins qu'il ne soit édité (désolé) –

Questions connexes