문제

I'm building my first WPF and MVVM application. I have 3 views (with 3 corresponding ViewModels)

1) MainWindow (Window)

2) ViewClients (UserControl)

3) ViewModClient (UserControl)

In Clients ViewModel I have a property SelectedClient that keeps track of the selected client on a DataGrid in the view. In this view, I also have a button related with an ICommand defined in MainWindow ViewModel. I resolve it with this binding:

Command="{Binding Path=DataContext.CreateViewsCommand, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type Window}}}" CommandParameter={x:Type local:ViewModClient}

I use CommandParameter to tell the mainWindow ViewModel which kind of view to create and keep the viewmodel isolated from views knowledge. This works great.

Now the problem:

In the ModClient ViewModel I need to load the client's data. So how do i relate this with the SelectedClient from Clients View while keeping the MVVM pattern? (I can only use one CommandParameter and it's already used)

도움이 되었습니까?

해결책

Caliburn.Micro for instance, got an built in IEventAggregator which allows you to create Eventmanagers which can be subscribed too. If you subscribe to this particular EventAggegrator with several ViewModels, you can define Messages that can be published and received from all ViewModels that have subscribed to this EventAggregator.

The following is just a short implementation and shows, how easy the communication between ViewModels can be, if you use a framework like Caliburn.Micro:

class ViewModel1 : PropertyChangedBase
{
    private IEventAggregator _Event;
    public ViewModel1(IEventAggregator events)
    {
        _Event = events;
        _Events.Publish(new TestEvent(5));
    }
}

class ViewModel2 : PropertyChangedBase, IHandle<TestEvent>
{
    private IEventAggregator _Events;
    public ViewModel2(IEventAggregator events)
    {
        _Events = events;
        _Events.Subscribe(this);
    }

    public void Handle(TestEvent message)
    {
        // do something with the incoming message
    }
}

class TestEvent
{
    public int foo { get; set; }
    public TestEvent(int someint)
    {
        foo = someint;
    }
}

It should be pretty self explanatory. However, if you have any questions, please let me know and I will get into more detail.

다른 팁

Typically this is done by using messaging.

All MVVM frameworks have a messaging bus to allow Inter-VM communication so just get a good framework and the task will get as simple as this (Simple MVVM Toolkit):

Source VM:

SendMessage(MessageTokens.SomeToken, new NotificationEventArgs<string>
            (MessageTokens.SomeToken, "MyMessage"));

Receiving VM:

RegisterToReceiveMessages<string>(MessageTokens.SomeToken, OnMessageReceived);

private void OnMessageReceived(object sender, NotificationEventArgs<string> e)
{
    // Code to execute upon message reception.
}
라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top