代码之家  ›  专栏  ›  技术社区  ›  si618

无法使用mvvm-light钩住PropertyChanged事件

  •  0
  • si618  · 技术社区  · 14 年前

    问候语,创建我的第一个基于MVVM的WPF应用程序,并试图找出为什么我无法钩住依赖属性的PropertyChanged事件。

    父视图模型中的代码:

    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 是ObservableCollection的简单扩展,用于封装视图。

    ClientViewModel 正在调用setter,但raisePropertiesChanged没有按我的预期工作,因为 onClientPropertyChanged 没有被调用。两个视图模型都继承自 ViewModelBase .

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

    如果我有线 PropertyChanged 到一个方法 客户视图模型 然后它被解雇了,所以我很难理解为什么它在父视图模型中不起作用。我哪里出错了?

    1 回复  |  直到 14 年前
        1
  •  1
  •   Community rcollyer    7 年前

    This SO question 解释问题;ObservableCollection保护PropertyChanged事件。

    一种解决方案是使用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()应该被重构,但是为了与问题代码保持一致,我将把它留在这里。然后对属性设置器进行细微更改:

    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);
        }
    }