locked
call method of view model from view (xaml.cs) RRS feed

  • Question

  • I have a question on calling a method of view model from view (xaml.cs). Any suggestions would be appreciated.

    The method works in view model since if I call the method in view model constructor, I will be able to see them data in DataGrid. But when I call the method in view (xaml.cs), the DataGrid in empty.

    In the view part, I have the code snippet below: (xaml.cs part)

     private ShellViewModel viewModel = new ShellViewModel();

            public ShellView()

            {

                this.DataContext = viewModel;

                InitializeComponent();

            }

    ......

            private void Button_Click(object sender, RoutedEventArgs e)

            {

                viewModel.Init();

            }// @@cannot call this method successfully

    Wednesday, September 9, 2015 5:04 AM

Answers

  • With MVVM you shouldn't have button click events which call methods on the viewmodel.

    The idea is to decouple the view and viewmodel and connect using bindings.

    Mostly you "do something" using commands.

    Please see this article:

    http://social.technet.microsoft.com/wiki/contents/articles/31915.wpf-mvvm-step-by-step-1.aspx

    That uses icommand, which is a bit clunky really.

    Mostly devs will use a framework like mvvm light or prism which offer more developer friendly ways to use icommand.

    For example:

        <Window.DataContext>
            <local:MainWindowViewModel/>
        </Window.DataContext>
        <Grid>
            <Button Command="{Binding DoInit}">Do Something</Button>
        </Grid>
    </Window>

    and

    using GalaSoft.MvvmLight;
    using GalaSoft.MvvmLight.CommandWpf;
    
    namespace wpf10
    {
        public class MainWindowViewModel :ViewModelBase
        {
            public RelayCommand DoInit { get; set; }
            private void init()
            {
                // Do initialisation or something
            }
            public MainWindowViewModel()
            {
                DoInit = new RelayCommand(init);
            }
        }
    }

    You can add mvvmlight to your project using nuget.

    Right click the project, choose manage nuget packages and search on mvvmlightlibs



    • Edited by Andy ONeill Wednesday, September 9, 2015 1:15 PM fixed name of command
    • Proposed as answer by Xavier Xie-MSFT Thursday, September 10, 2015 3:18 AM
    • Marked as answer by Xavier Xie-MSFT Wednesday, September 16, 2015 9:13 AM
    Wednesday, September 9, 2015 7:39 AM

All replies

  • Hi,

    Try to move "this.DataContext = viewModel" after "InitializeComponent".Or better:

    Set the datacontext in the loaded event of the window. You should not use the constructor for this.

    Rgds MM


    PS: Please mark as answer if helpful. Thanks!
    Blog: http://www.manuelmeyer.net
    Twitter: https://twitter.com/manumeyer1

    Wednesday, September 9, 2015 7:27 AM
  • With MVVM you shouldn't have button click events which call methods on the viewmodel.

    The idea is to decouple the view and viewmodel and connect using bindings.

    Mostly you "do something" using commands.

    Please see this article:

    http://social.technet.microsoft.com/wiki/contents/articles/31915.wpf-mvvm-step-by-step-1.aspx

    That uses icommand, which is a bit clunky really.

    Mostly devs will use a framework like mvvm light or prism which offer more developer friendly ways to use icommand.

    For example:

        <Window.DataContext>
            <local:MainWindowViewModel/>
        </Window.DataContext>
        <Grid>
            <Button Command="{Binding DoInit}">Do Something</Button>
        </Grid>
    </Window>

    and

    using GalaSoft.MvvmLight;
    using GalaSoft.MvvmLight.CommandWpf;
    
    namespace wpf10
    {
        public class MainWindowViewModel :ViewModelBase
        {
            public RelayCommand DoInit { get; set; }
            private void init()
            {
                // Do initialisation or something
            }
            public MainWindowViewModel()
            {
                DoInit = new RelayCommand(init);
            }
        }
    }

    You can add mvvmlight to your project using nuget.

    Right click the project, choose manage nuget packages and search on mvvmlightlibs



    • Edited by Andy ONeill Wednesday, September 9, 2015 1:15 PM fixed name of command
    • Proposed as answer by Xavier Xie-MSFT Thursday, September 10, 2015 3:18 AM
    • Marked as answer by Xavier Xie-MSFT Wednesday, September 16, 2015 9:13 AM
    Wednesday, September 9, 2015 7:39 AM
  • Bind your viewmodel after InitializeComponent();

            VMSigLog _vm = new VMSigLog();
            public SigLog()
            {
                InitializeComponent();
                base.DataContext = _vm;
             
            }

    avoid code behind event, use ICommand



    Regards atik sarker

    Wednesday, September 9, 2015 8:05 AM
  • >>But when I call the method in view (xaml.cs), the DataGrid in empty.

    What is the method doing? Make sure that you are calling the Init() method of the very same instance of the view model that your UI elements are bound to. You should for example not set the DataContext of any element in the XAML markup like this:

    <Window.DataContext>
            <vm:ShellViewModel />
        </Window.DataContext>

    Then you are setting the DataContext to another instance of the viewmodel than the one referenced by the "viewModel" field in your code-behind class and thus you are calling the Init() method of the wrong instance.

    If you set the DataContext property after the call to the InitializeComponent() method the instance that you create in the XAML markup is never used:

    public ShellView()
            {
                 InitializeComponent();
                 this.DataContext = viewModel;
            }

    Please provide a reproducible sample of your issue by uploading a project to OneDrive and post the link to it here if you need any further help.

    You might also want to read my blog post about how to handle events, such as the Clicked event for a Button, in MVVM: http://blog.magnusmontin.net/2013/06/30/handling-events-in-an-mvvm-wpf-application/.


    Hope that helps.

    Please remember to close your threads by marking helpful posts as answer and then start a new thread if you have a new question. Please don't ask several questions in the same thread.

    Wednesday, September 9, 2015 1:00 PM