I have been working with a sample WPF MVVM project (VS2012) which introduces the [CallerMemberName] attribute. This seems pretty cool because you don't have to include the property name when raising the PropertyChanged event. My issue (is mostly with this sample project) is that if I comment out the call to raise the PropertyChanged event, the program still runs normanlly -- no changes in the behavior of the program. Is this because of the [CallerMemberName] attribute? Actually, I noticed that this project does not use an Action delegate . The project contains a FlowDocument, a button, and a Datagrid and does not contain any toolkit or other framework assemblies -- it was just created from out of the box of VS2012 WPF template. When you click the button (in the window in the image below) the program writes some data to the datagrid. My request is if someone could look at the project code below (below the image) and suggest a change to the code (maybe how I could implement ICommand and use a command) where it would make a difference (change the behavior of the program) if I WERE to comment out the call to raise the PropertyChanged event (NotifyPropertyChanged();). Note: the original author created this sample project with all the project code (all the classes) contained in the code behind module of MainWindow.xaml (this was actually good for me because I took the opportunity to separate all the classes out into the conventional MVVM format -- Model folder, View folder, ViewModel folder -- I provided a link above the image below here for downloading a .zip of my version of the sample project - a working version -- with No code behind the main window -- I use a datacontext in Window1.xaml).
When I click on the 'Add New Person' button (in the image above) it just adds the current time (the time the button was clicked) to the grid. How could I modify the code so that if I comment out the NotifyPropertyChanged(); call -- the behavior is different than if I leave that call uncommented (right now there is no change in the behavior of the program when I click the 'Add New Person' button whether NotifyPropertyChanged(); is commented out or not). Would it be possible to use an Action delegate in this project? How to do that?
While I'm at it, I have one other request (if someone would care to do this) which would be to explain if using a toolkit like MVVMlight would make a difference in the coding of this particular sample project (but keep the same functionality), or explain if for this particular project it would not make any difference if I were to use a toolkit like MVVMlight.
using System; using System.Collections.ObjectModel; using System.ComponentModel; using System.Runtime.CompilerServices; using System.Windows; using System.Windows.Input; namespace TheWorldsEasiestMVVM { public partial class MainWindow : Window { public MainWindow() { InitializeComponent(); } } public class MainWindowViewModel : INotifyPropertyChanged { public MainWindowViewModel() { MainWindowModel mwm = new MainWindowModel(); OC = mwm; } private ObservableCollection<Person> _OC = null; public ObservableCollection<Person> OC { get { return _OC; } set { _OC = value; NotifyPropertyChanged(); } } public event PropertyChangedEventHandler PropertyChanged; private void NotifyPropertyChanged([CallerMemberName] String propertyName = "") { if (PropertyChanged != null) { PropertyChanged(this, new PropertyChangedEventArgs(propertyName)); } } } public class MainWindowModel : ObservableCollection<Person> { public MainWindowModel() { this.Add(new Person { LastName = "FirstLastName", FirstName = "FirstFirstName" }); this.Add(new Person { LastName = "SecondLastName", FirstName = "SecondFirstName" }); this.Add(new Person { LastName = "ThirdLastName", FirstName = "ThirdFirstName" }); //And then wires up a event listener to the AddNewPerson Command to add it to the collection. AddNewPersonE.OnNewPerson += new NotifyS(AddNewPerson_OnNewPerson); } //Here's the event listener who is notified when a new person is added via the click of a button private void AddNewPerson_OnNewPerson(Person p) { this.Add(p); } } public class Person { public String LastName { get; set; } public string FirstName { get; set; } } public delegate void NotifyS(Person p); public class AddNewPersonE : ICommand { public static event NotifyS OnNewPerson; private bool _CanExecute = true; public bool CanExecute(object parameter) { return _CanExecute; } public event EventHandler CanExecuteChanged; public void Execute(object parameter) { //this tells WPF to keep the button disabled. _CanExecute = false; //not much of a person name, but you get the idea. Person p = new Person { LastName = DateTime.Now.ToLongTimeString() + "--xxMM", FirstName = DateTime.Now.ToLongTimeString() + "--YYzz"}; if (OnNewPerson != null) { OnNewPerson(p); } //re-enable the button... _CanExecute = true; } } }
Rich P