locked
How to call a method of loaded viewmodel in another view RRS feed

  • Question

  • Hi,

    I have buttons in my mainpage.xaml

    I have a view1.xaml with tab control displayed along with mainpage.xaml(Using Page Transition). Each tab Item has a view model(Viewmodel1,viewmodel2..) as data context assigned. 

    Now problem is that ,when I change something in my tab control view model and click on the mainpage.cs buttons, I need to call save functionality which is there under viemodel1.

    If I call ViewModel1 Obj = new ViewModel1();  ---> User Entered values are going off as viewmodel1 is called as new.

    Could anyone help me out.

    Thanks In Advance,

    Bharani.

    Monday, November 30, 2015 6:22 AM

Answers

  • >>If I call ViewModel1 Obj = new ViewModel1();  ---> User Entered values are going off as viewmodel1 is called as new.

    That's because you are creating a new instance of your ViewModel1 class. You want to reference the already existing one and call the Save method of this one instead of creating a new instance.

    You could do this by accessing a reference to the ViewModel1 class. Of course this requires you to have saved any such reference somewhere. Or if you can access the TabItem, you could cast its DataContext property:

    ViewModel1 Obj = tabItem1.DataContext as ViewModel1;
    Obj.Save();

            <TabControl>
                <TabItem x:Name="tabItem1" Header="1"></TabItem>
            </TabControl>

    Another option is to send a "save" message from the MainPage and then subscribe to and handle this message in the ViewModel1 class. This requires you to use a messenger or an event aggregator. Please refer to my blog post for more information about this: http://blog.magnusmontin.net/2014/02/28/using-the-event-aggregator-pattern-to-communicate-between-view-models/.

    The sample code uses the EventAggregator class that is available in Prism (https://www.nuget.org/packages/Prism.Wpf/) but you could also use another library such as for example MvvmLight: http://stackoverflow.com/questions/16993918/mvvm-light-messenger-sending-and-registering-objects. The concept is the same.

    You define a message class and send a message from the MainPage and subscribe to and handle this event in the view model class as described in the blog post and on the Stackoverflow link above. You may find it easier to just cast the DataContext property of the TabItem or just save a reference to the ViewModel when you assign the TabItem an initial DataContext though:

    ViewModel1 Obj;
     public MainWindow() {
                InitializeComponent();
    Obj = new ViewModel1();
    tabItem1.DataContext = Obj;
    }
    
    private void Save()
    {
    Obj.Save();
    }

    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.

    Monday, November 30, 2015 3:14 PM

All replies

  • It's not at all clear to me what has which viewmodel from your description.

    There's a view1 and a mainpage and some tab items involved somehow.

    One way to keep viewmodels decoupled but initiate a method in one from another is to use mvvm light messenger.

    You can send a message from whatever viewmodel the command your button is in and act on that message in whatever viewmodel your save functionality is in.

    The pattern is explained here:

    http://social.technet.microsoft.com/wiki/contents/articles/26070.communicating-between-classes.aspx

    From the button command initiating this:

    var msg = new DoSomethingMessage { SomeProperty = AnythingYouWantToPass };
    Messenger.Default.Send<DoSomethingMessage >(msg);

    You subscribe to that type over in the thing needs to act:

        

    //ctor

    Messenger.Default.Register<DoSomethingMessage >(this, (action) => ReceiveDoSomethingMessage(action)); } private void ReceiveDoSomethingMessage(DoSomethingMessage msg) { // Call your method. }


    One of my samples uses this approach to drive editing commands on whichever view(model) is active:

    http://social.technet.microsoft.com/wiki/contents/articles/30103.c-practical-poly.aspx


    Hope that helps.

    Technet articles: WPF: MVVM Step 1; All my Technet Articles

    Monday, November 30, 2015 7:58 AM
  • >>If I call ViewModel1 Obj = new ViewModel1();  ---> User Entered values are going off as viewmodel1 is called as new.

    That's because you are creating a new instance of your ViewModel1 class. You want to reference the already existing one and call the Save method of this one instead of creating a new instance.

    You could do this by accessing a reference to the ViewModel1 class. Of course this requires you to have saved any such reference somewhere. Or if you can access the TabItem, you could cast its DataContext property:

    ViewModel1 Obj = tabItem1.DataContext as ViewModel1;
    Obj.Save();

            <TabControl>
                <TabItem x:Name="tabItem1" Header="1"></TabItem>
            </TabControl>

    Another option is to send a "save" message from the MainPage and then subscribe to and handle this message in the ViewModel1 class. This requires you to use a messenger or an event aggregator. Please refer to my blog post for more information about this: http://blog.magnusmontin.net/2014/02/28/using-the-event-aggregator-pattern-to-communicate-between-view-models/.

    The sample code uses the EventAggregator class that is available in Prism (https://www.nuget.org/packages/Prism.Wpf/) but you could also use another library such as for example MvvmLight: http://stackoverflow.com/questions/16993918/mvvm-light-messenger-sending-and-registering-objects. The concept is the same.

    You define a message class and send a message from the MainPage and subscribe to and handle this event in the view model class as described in the blog post and on the Stackoverflow link above. You may find it easier to just cast the DataContext property of the TabItem or just save a reference to the ViewModel when you assign the TabItem an initial DataContext though:

    ViewModel1 Obj;
     public MainWindow() {
                InitializeComponent();
    Obj = new ViewModel1();
    tabItem1.DataContext = Obj;
    }
    
    private void Save()
    {
    Obj.Save();
    }

    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.

    Monday, November 30, 2015 3:14 PM