Search code examples
mvvmicommand

ICommand not binding in Loaded event using MVVMLight framework


I am wondering why binding a button inside the Loaded event in WPF page does not work and will only work after navigating to another page, and going back.

I have an inventory app and on the main page, most of the ViewModel are called because of a Back button which goes back to a specific lists and what causes that is, it will start binding the even if that command is not for that page and it will also load the collections for other pages.

So I used Loaded page event to call the necessary methods to populate the lists and also start binding commands for this specific page. I also used Unloaded page event for clean up like unsubscribing to some CRUD events.

The problem now though is, buttons does not get binding in Loaded page event. I do not know why..

I have made a miniature app to demo the problem. It can be downloaded here (full source code included) https://www.dropbox.com/s/qzumzyicuvrktsi/ICommandTest.zip?dl=0 enter image description here


Solution

  • This is because your views are not getting notified about the change of Command_ShowAddWindow and Command_ClickMe. Let me explain:

    When your Page constructor is first run the bindings to your commands are initialized and transferred to the view, but by that time your commands are null, so the view binds both buttons' commands to null.

    Then when your Loaded event is fired the commands are initialized, but the view is not getting notified about it, so it keeps command bindings to null.

    The solutions to the problem are:

    You manually call RaisePropertyChanged to notify the view about commands change when you initialize them:

    void InitCommands()
    {
        Command_ShowAddWindow = new RelayCommand(Command_ShowAddWindow_Click);
        Command_ClickMe = new RelayCommand(Command_ClickMe_Click);
        RaisePropertyChanged("Command_ShowAddWindow");
        RaisePropertyChanged("Command_ClickMe");
    }
    

    Or you initialize your commands in your ViewModel constructor before DataBindings are initialized:

    public ViewModel_Page1()
    {
        InitCommands();
        ...
    }