Click here to Skip to main content
14,695,235 members
Please Sign up or sign in to vote.
5.00/5 (1 vote)
See more:
Hi dear experts I need your help. I have a collection of childs in my ViewModel, each child has some properties. I have created an interface using ListBox template items. Each property of child object is bind with a control let say with a dropdown or with a text box. Now I want to notify my ViewModel if any change occurs in the any property of a child object.


Regards
Posted
Updated 9-Mar-14 23:51pm
v2

1 solution

There are various ways of achieving this (and various MVVM frameworks that does it for you, to a degree) and it all depends on the context.
If you have a fairly static set of children (static as is static for the life of the owning view model) then having the owing view model connect to the
INotifyPropertyChanged.PropertyChanged event on each child might work for you.

If on the other hand the list of children changes so that the owning view model would have to subscribe and unsubscribe to child events then that might be a little messy.

Consider the following simple example;

Notifier
using System.ComponentModel;
namespace WpfApplication {
    public class Notifier : INotifyPropertyChanged {
        public event PropertyChangedEventHandler PropertyChanged;
        protected void Notify(string propertyName) {
            var handler = PropertyChanged;
            if (handler != null)
                handler(this, new PropertyChangedEventArgs(propertyName));
        }
    }
}

ChildModel
namespace WpfApplication {
    public class ChildModel {
        private readonly string name;
        public string MutableValue { get; set; }

        public ChildModel(string name, string mutableValue) {
            this.name = name;
            MutableValue = mutableValue;
        }

        public string Name {
            get { return name; }
        }
    }
}

MainModel
using System.Collections.Generic;

namespace WpfApplication {
    public class MainModel {

        private readonly string name;
        private readonly IEnumerable<ChildModel> children;

        public MainModel(string name, IEnumerable<ChildModel> children) {
            this.name = name;
            this.children = children;
        }

        public string Name {
            get { return name; }
        }

        public IEnumerable<ChildModel> Children {
            get { return children; }
        }
    }
}

ChildViewModel
namespace WpfApplication {
    public class ChildViewModel : Notifier {
        private readonly ChildModel model;

        public ChildViewModel(ChildModel model) {
            this.model = model;
        }

        public string MutableValue {
            get { return model.MutableValue; }
            set {
                if (value == model.MutableValue) 
                    return;

                model.MutableValue = value;
                Notify("MutableValue");
            }
        }
    }
}

MainViewModel
using System.Collections.Generic;
using System.Linq;
using System.ComponentModel;

namespace WpfApplication {
    public class MainViewModel {
        private readonly MainModel model;
        private readonly IEnumerable<childviewmodel> children;

        public MainViewModel(MainModel model) {
            this.model = model;

            children = model.Children.Select(child => new ChildViewModel(child)).ToList();
            foreach (var child in children) {
                child.PropertyChanged += OnChildPropertyChanged;
            }
        }

        private void OnChildPropertyChanged(object sender, PropertyChangedEventArgs e) {
            var child = sender as ChildViewModel;
            // Do something awesome here!
        }

        public string Name {
            get { return model.Name; }
        }

        public IEnumerable<childviewmodel> Children {
            get { return children; }
        }
    }
}
</childviewmodel></childviewmodel>


In this case the events from the ChildViewModel are monitored by the owning view model, MainViewModel, and the hooking up to the event is the responibility of the MainViewModel and is done in its constructor as it creates view models from models of the children.

Again; a setup like this might turn messy if you need to;

  • Dynamically add/remove children
  • There are many properties on the ChildViewModel and the MainViewModel needs to do different things depending on which property was changed.
  • The type of children vary


Hope this helps,
Fredrik
   

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)




CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900