Windows Phone 8具有MVVM的一个页面的多个实例

时间:2014-03-12 17:17:04

标签: c# mvvm windows-phone-8 windows-phone mvvm-light

我正在编写Windows Phone聊天应用程序,我想实现ChatPage,它将用于保持对话视图。整个想法是创建尽可能与SMS页面类似的视图,并在该页面的实例之间切换。

问题就出现了 - 在每个页面实例上,我需要绑定存储在XML文件中的ContactContactMessages。我认为从Contact的XML文件中获取正确的消息可以简单地用构造函数编写。但是如何打开新的页面实例并发送Contact

我正在使用MVVM Light工具包,我可以使用Messanger来完成它,但我怎样才能确保我的Contact不会在其他页面实例中注册。在这种情况下注册ChatPageViewModel的实例无法在ViewModelLocator中实现,因为我需要使用ViewModel的多个实例(如果我错了,请训斥我,我是MVVM中的新手光)。

有没有办法实现这一目标?或者也许我正在考虑的方式是完全错误的?

2 个答案:

答案 0 :(得分:0)

您可以尝试使用界面制作服务。当客户点击联系人时,传递此服务可以搜索的参数,并使用联系人返回消息。每个需要此服务的ViewModel都可以从构造函数中提取它。只需要一些参数来知道要读取哪个xml。

我不知道是否是IoC容器。 Unity或Autofac或其他人也可以解决您的问题。

如果您使用Autofac,您可以拥有与此类似的类:

public class ViewModelLocator
{
    private IContainer container;
    public ViewModelLocator()
    {
        ContainerBuilder builder = new ContainerBuilder();

        builder.RegisterType<MainViewModel>();

        container = builder.Build();
    }

    public MainViewModel MainViewModel
    {
        get { return container.Resolve<MainViewModel>(); }
    }
}

你可以像这样的参数一样使用这个实例:

builder.RegisterType<MainViewModel>().InstancePerDependency();

builder.RegisterType<MainViewModel>().InstancePerLifetimeScope();

builder.RegisterType<MainViewModel>().SingleInstance();

了解更多信息here for Autofachere for Unity

希望有所帮助。问候!

答案 1 :(得分:0)

基于MVVM Light,我会选择这种情况:

在中央页面上,您有一个所有联系人列表。一旦用户选择一个联系人,您就会广播一条已选择联系人的消息。会话视图模型订阅此消息并从模型加载会话。联系人视图模型使用navigation service导航到会话视图。

(部分)联系人ViewModel:

public ContactsViewModel(IDataService dataService, INavigationService navigationService)
{
    _dataService = dataService;
    _navigationService = navigationService;
}

private RelayCommand _showConversation;

public RelayCommand ShowEvents
{
    get
    {
        return _showConversation ?? (_showConversation = new RelayCommand(ExecuteShowConversation));
    }
}

private void ExecuteShowConversation()
{
    Messenger.Default.Send(new ContactSelectedMessage(){Contact = Contact);
    _navigationService.NavigateTo(new Uri("/Views/ConversationView.xaml", UriKind.RelativeOrAbsolute));
}

(部分)对话ViewModel:

public ConversationViewModel(IDataService dataService, INavigationService navigationService)
{
    _dataService = dataService;
    _navigationService = navigationService;
    Messenger.Default.Register<ContactSelectedMessage>(this, OnContactSelected);
}

private void OnContactSelected(ContactSelectedMessage contactSelectedMessage)
{
    _dataService.GetConversation(contactSelectedMessage.Contact);
}

为了使viewmodel接收消息,应在广播消息之前对其进行实例化。因此,您必须在ViewModelLocator中实例化它。

在ViewModelLocator中:

static ViewModelLocator()
{
    /// parts missing for brevity

    SimpleIoc.Default.Register<IDataService, DataService>();
    SimpleIoc.Default.Register<INavigationService, NavigationService>();
    SimpleIoc.Default.Register<ContactsViewModel>();
    SimpleIoc.Default.Register<ConversationViewModel>(true);
}