使用MVVMLight将变量传递给第二个窗口?

问题描述:

我正在构建一个应用程序来教自己MVVM和一些Google搜索(以及一些试用错误)我已经设法达到了可以从ViewModel打开第二个窗口的程度,但不能将变量从一个页面传递到另一个。这是我的ViewModel。使用MVVMLight将变量传递给第二个窗口?

public VendorSelectViewModel() 
    { 
     Ping ping = new Ping(); 
     PingReply pingresult = ping.Send("192.168.1.10"); 
     if (pingresult.Status.ToString() == "Success") 
     { 
      LoadVendorsAsync(); 
     } 
     else 
     { 
      LoadVendors(); 
     } 

     NextCommand = new RelayCommand(NextWindow); 
    } 

    public ICommand NextCommand { get; private set; } 

    void NextWindow() 
    { 
     Console.WriteLine(selectedVendor.VendorName); 
     Messenger.Default.Send(new NotificationMessage("NextWindow")); 
    } 

在我看来,我有这个

public VendorSelectWindow() 
    { 
     InitializeComponent(); 
     _vm = new Biz.Invoicer.VendorSelectViewModel(); 
     DataContext = _vm; 

     Messenger.Default.Register<NotificationMessage>(this, NotificationMessageReceived); 
    } 

    private void NotificationMessageReceived(NotificationMessage msg) 
    { 
     if (msg.Notification == "NextWindow") 
     { 
      var invoicerWindow = new InvoicerWindow(); 
      invoicerWindow.Show(); 
     } 
    } 

所以我知道(或我想我知道)这可能不是一个“最佳实践”,但我会回来这一点,并重构为我更好地了解MVVM模板和MVVM Light。目前我正在尝试将第一页(VendorSelectViewModel)的ViewModel变量传递给第二页(InvoicerWindow),但是我没有设法修改语法。

我需要做什么才能将变量从一页传递到下一页?

首先,您可以传递任意对象作为IMessenger.Send<TMessage>方法的参数 - TMessage类型参数不受限制。例如:

//ViewModel: 
void NextWindow() 
{ 
    //... 
    int someValue = 10; 
    Messenger.Default.Send(someValue); 
} 

//View: 
public VendorSelectWindow() 
{ 
    //... 
    Messenger.Default.Register<int>(this, MessageReceived); 
} 

private void MessageReceived(int value) 
{ 
    //... 
} 

然而,如果你发现NotificationMessage类,你的情况是特别有用的,你可以利用通用NotificationMessage<T>版本,它公开任意类型T的附加属性Content

//ViewModel: 
void NextWindow() 
{ 
    //... 
    int someValue = 10; 
    Messenger.Default.Send(new NotificationMessage<int>(someValue, "Notification text")); 
} 

//View: 
public VendorSelectWindow() 
{ 
    //... 
    Messenger.Default.Register<NotificationMessage<int>>(this, MessageReceived); 
} 

private void MessageReceived(NotificationMessage<int> message) 
{ 
    var someValue = message.Content; 
    //... 
} 

或者,如果这不适合你,你可以创建自己的类,从NotificationMessage派生出来并公开其他成员并将其用作消息对象。

+0

我更喜欢创建我自己的类的选项,因为它明确发生在接收(注册)方面。每种类型的事件一个类。 SelectedVendorChangedNotificationMsg,SelectedVendorDeletedNotificationMsg ...等等。 – Fredrik

不是传递一个NotificationMessage的使者,你可以通过自己的自定义类型的实例,它可以携带尽可能多的价值,你想:

void NextWindow() 
{ 
    Console.WriteLine(selectedVendor.VendorName); 
    Messenger.Default.Send(new YourPayload() {WindowName = "NextWindow", Parameter = "some value..:"); 
} 
... 

public VendorSelectWindow() 
{ 
    InitializeComponent(); 
    _vm = new Biz.Invoicer.VendorSelectViewModel(); 
    DataContext = _vm; 

    Messenger.Default.Register<YourPayload>(this, NotificationMessageReceived); 
} 

private void NotificationMessageReceived(YourPayload msg) 
{ 
    if (msg.WindowName == "NextWindow") 
    { 
     string param = msg.Parameter; 
     var invoicerWindow = new InvoicerWindow(); 
     invoicerWindow.Show(); 
    } 
} 

YourPayload是具有两个属性,WindowName和自定义类Parameter