【问题标题】:Passing parameter between ViewModels using MVVMLight使用 MVVMLight 在 ViewModel 之间传递参数
【发布时间】:2015-02-05 11:04:36
【问题描述】:

我在使用 MVVMLight 框架中的 Messenger 类在我的 ViewModel 之间传递参数时遇到问题。

这是我正在使用的代码:

ViewModelLocator

public ViewModelLocator ()
{
    ServiceLocator.SetLocatorProvider(() => SimpleIoc.Default);

    SimpleIoc.Default.Register<INavigationService, NavigationService>();

    SimpleIoc.Default.Register(() => new MainViewModel(NavigationService));
    SimpleIoc.Default.Register(() => new SecondViewModel(NavigationService));
}

public MainViewModel MainViewModel
{
    get { return SimpleIoc.Default.GetInstance<MainViewModel>(); }
}

public SecondViewModel SecondViewModel
{
    get { return SimpleIoc.Default.GetInstance<SecondViewModel>(); }
}

public INavigationService NavigationService
{
    get { return SimpleIoc.Default.GetInstance<INavigationService>(); }
}

MainViewModel

private void ShowPersonDetailsCommand(object obj)
{
    Messenger.Default.Send((Person)obj);
    _navigationService.NavigateTo(new Uri("/SecondPage.xaml", UriKind.Relative))
}

SecondViewModel

public SecondViewModel(INavigationService navigationService)
{
    _navigationService = navigationService;

    Messenger.Default.Register<Person>(
        this,
        person =>
        {
            Person = person;
        });
}

在我的MainViewModel (ShowPersonDetailsCommand) 中,我正在导航到 SecondPage 并在 Messenger 类中发送一个人作为参数。在这一点上,此人已构建良好并作为消息发送。

但在SecondViewModel 构造函数中,人为空:(

我有什么遗漏吗?

我认为我做错了什么......

供您参考:

  • Windows Phone 8.1(Silverlight)

  • MVVMLight 5.0.2

  • Visual Studio 2013 更新 4

【问题讨论】:

    标签: c# silverlight windows-phone-8.1 mvvm-light viewmodellocator


    【解决方案1】:

    我建议在ViewModelLocator 中注册后立即创建SecondViewModel。您可以通过使用Register 的重载方法来做到这一点。

    SimpleIoc.Default.Register<SecondViewModel>(true);
    

    这将确保Messenger 注册发生在消息发送之前。

    【讨论】:

      【解决方案2】:

      当您发送消息时,SecondViewModel 尚未创建;它仅在您访问ViewModelLocatorSecondViewModel 属性时创建。因此,您的消息已发送,并且没有任何处理。然后,当SecondViewModel 实例创建时,消息已经发送了......

      我建议你在通话后将消息发送到NavigateTo,它应该可以解决问题。

      【讨论】:

      • 我做到了,但它没有改变任何东西:(
      • @Christophe,您的 NavigationService 是如何实现的? NavigateTo 方法可以带一个参数传递到目标页面吗?如果可以的话,这可能是在 ViewModel 之间传递数据的更好方法......
      • 我的 NavigationService 可以将状态(对象)作为参数。但问题是我不想在后面的代码中得到这个参数。因为 AFAIK 我们只有在覆盖 OnNavigatedTo 时才能获得该状态!
      【解决方案3】:

      您可以在 NavigationServicesEx.Navigate 方法调用中传递一个参数,而不是发送消息。

      Marco Minerva 的 blog 建议如何挂钩 Frame_Navigating 事件(它从 vanilla NavigationServiceEx 类中丢失)以在导航到目标页面时访问参数。

      创建博客中描述的 INavigable 接口:

      public interface INavigable
      {
          Task OnNavigatedToAsync(object parameter, NavigationMode mode);
          void OnNavigatingFrom(NavigatingCancelEventArgs e);
          void OnNavigatedFrom();
      }
      

      在 NavigationServicesEx 类中为 Frame.Navigating 事件添加一个处理程序(带有一些额外的管道,请参阅博客),然后在您的 ViewModels 中实现 INavigable 接口。

      然后您将能够访问您在 Navigate 调用中传递的参数:

      NavigationServiceEx.Navigate(typeof(DestinationPage).FullName, yourParameter);
      

      在您在 ViewModel 中实现的 OnNavigatedToAsync 方法中:

      public Task OnNavigatedToAsync(object parameter, NavigationMode mode)
      {
          if (parameter != null)
          {
              YourThing thing = parameter as YourThing;
              this.UseYourThing(thing);
          }
          return Task.CompletedTask;
      }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2019-01-12
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2023-01-08
        • 2021-01-08
        相关资源
        最近更新 更多