简体   繁体   中英

WPF - Binding and Command on two different ViewModel

it goes like this.. I have two viewModels under one same XAML file.

ViewModel(1) - Contains a button that has a command that will fire a function inside that view model.

ViewModel(2) - Contains a property that are binded to the XAML

Question : Is it possible for me to update that particular property in ViewModel(2) using the command in ViewModel(1) ? If yes, can I have a brief guideline on how to approach it?

The requirement sets me not to make any changes like shifting the property to be in the same viewModel as the command .

Thank you in advance for any help guys :)

I think you should use a Messenger.
Here is a good article about Messenger in mvvm architecture.
A little bit old, but it could help you imo : https://msdn.microsoft.com/en-us/magazine/jj694937.aspx

Here is an example, for you. For instance, I use MVVM Light from Galasoft, to be the most straightforward as possible :) http://www.galasoft.ch/mvvm/

First of all, I recommand you to create an Entity related to your message you want to broadcast :
I have added a simple string property, but obviously you can add whatever you want :)

public class Vm1toVm2Message
{
    public String Message { get; set; }
}

Then in your VM1 you create your message and broadcast it :

public class ViewModel1 : ViewModelBase
{
    private RelayCommand _refreshCommand;
    public RelayCommand RefreshCommand
    {
        get
        {
            return _refreshCommand ?? (_refreshCommand = new RelayCommand(() =>
            {
                // You button command code
                // -------------------

                // Send a message
                Messenger.Default.Send<Vm1toVm2Message>( new Vm1toVm2Message { Message = "Update from VM1" });
            }));
        }
    }
}

And finally in your VM2, you wait for an incoming message :)

public class ViewModel2 : ViewModelBase
{
    public ViewModel2()
    {
        Messenger.Default.Register<Vm1toVm2Message>(this, HandleVm1toVm2Message);
    }

    private void HandleVm1toVm2Message(Vm1toVm2Message msg)
    {
        // Do what you want here
    }
}

You can try this :

public class FirstViewModel : INotifyPropertyChanged
{
    public delegate void PropertyChangedHandler(object obj);
    public static event PropertyChangedHandler MyPropertyChanged = delegate { };
    public FirstViewModel()
    {
        //Example: here I fire the function in the second ViewModel with parameter
        var obj = new { Name = "Jhon" };
        MyPropertyChanged(obj);
    }
}

Second ViewModel

public class SecondViewModel : INotifyPropertyChanged
{
    public SecondViewModel()
    {
        FirstViewModel.MyPropertyChanged += OnMyPropertyChanged;
    }

    public void OnMyPropertyChanged(object obj)
    {
        //...
    }

    //....
}

In viewmodel 1 you can store an action which updates the property in viewmodel 2. In viewmodel 1 you cann invoke the action and viewmodel 2 is changed.

public class SomeOtherClass
{
    public void main()
    {
        var vm1 = new ViewModel1();
        var vm2 = new ViewModel2();

        vm1.ChangeValueAction = new Action(() => { vm2.SomeProperty = String.Empty; });
    }
}

public class ViewModel1
{
    public Action ChangeValueAction { get; set; }

    public void SomeMethod()
    {
        ChangeValueAction.Invoke();
    }
}

public class ViewModel2
{
    public string SomeProperty { get; set; }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM