简体   繁体   English

WPF-将单个模型与多个ViewModels一起使用

[英]WPF - Use a single Model with multiple ViewModels

How would you allow multiple viewmodels to share the same model? 您如何允许多个视图模型共享同一模型?

I'm creating the viewmodels in an ApplicationViewModel that is used for switching between views using a DataTemplate with the selected VM. 我正在一个ApplicationViewModel中创建视图模型,该视图模型用于使用带有选定VM的DataTemplate在视图之间进行切换。

public ApplicationViewModel()
{
    //Add pages
    BasePageViewModels.Add("Home Page", new HomeViewModel());
    BasePageViewModels.Add("Summary Page", new SummaryViewModel());
    BasePageViewModels.Add("AddTestRun Page", new AddTestRunViewModel());
    //some code here
    CurrentBasePageViewModel = BasePageViewModels["Home Page"];
}

I want to be able to access the same Data class from within each of the created VM's. 我希望能够从每个创建的VM内访问相同的Data类。 Ideally I'd pass in the Data class to each ViewModel with a parameter but that then causes setting DataContex within XAML to throw an error because the DataContext has no accessible constructors. 理想情况下,我会将带参数的Data类传递给每个ViewModel,但这会导致XAML中设置DataContex引发错误,因为DataContext没有可访问的构造函数。

Update 更新资料

I'm setting the DataContext in the other Views like so: 我在其他视图中设置DataContext,如下所示:

<UserControl.DataContext>
    <viewModels:SummaryViewModel/>
</UserControl.DataContext>

but doing that creates a new instance of the ViewModel, rather than using the one bound to CurrentBasePageViewModel . 但是这样做会创建ViewModel的新实例,而不是使用绑定到CurrentBasePageViewModel

Definitelly, the solution is to pass model to viemodel's constructor. 绝对,解决方案是将模型传递给viemodel的构造函数。

Now, how to solve your problem with xaml? 现在,如何使用xaml解决您的问题?

First of all, from your question and posted code it is not clear, what's the problem. 首先,从您的问题和已发布的代码尚不清楚,这是什么问题。 (the xaml code is missing). (xaml代码丢失)。

I just guess, the problem is causing design time datacontext, since it requires parameterless constructor. 我只是猜测,这个问题导致了设计时数据上下文,因为它需要无参数的构造函数。 There are two solutions: 有两种解决方案:

  1. Add parameterless constructor: 添加无参数构造函数:

     public class MyViewModel { public MyViewModel(){ //design time ctor. Create design time data here } public MyViewModel(MyModel model){...} } 
  2. Create new class for design time datacontext: 为设计时数据上下文创建新类:

     public class MyViewModelDesignTime : MyViewModel { public MyViewModelDesignTime() : base(new MyModel()){ //design time ctor. Create design time data here } } 

    and use this class in xaml: 并在xaml中使用此类:

      d:DataContext="{d:DesignInstance l:MyViewModelDesignTime, IsDesignTimeCreatable=True}" 

try something like this: 尝试这样的事情:

HomeViewModel _homeViewModel;
SummaryViewModel _summaryViewModel;
public ApplicationViewModel()
{
    //Add pages
    _homeViewModel = new HomeViewModel();
    _summaryViewModel = new SummaryViewModel();

    //some code here
    _homeViewModel.SomeProperty = 5;
    CurrentBasePageViewModel = _homeViewModel;
}

Then some int property of your view homeViewModel will have value 5. Also you can create property in homeViewModel that will hold reference to current ApplicationViewModel or create interface. 然后,您的视图homeViewModel的一些int属性将具有值5。您还可以在homeViewModel中创建属性,该属性将保留对当前ApplicationViewModel的引用或创建接口。 Example of the interface: 接口示例:

public interface IName
{       
    /// <summary>
    /// Property name.
    /// </summary>
    string PropertyName { get; }
}

Then make ApplicationViewModel implement this interface and pass it to viewmodel. 然后使ApplicationViewModel实现此接口,并将其传递给viewmodel。 In viewModel create property. 在viewModel中创建属性。 Something like: 就像是:

public class HomeViewModel
{
     IName _iName;
     public HomeViewModel(IName name)
     {
          _name = name;
     }
}

And your ApplicationViewModel: 和您的ApplicationViewModel:

public class ApplicationViewModel : IName
{
    HomeViewModel _homeViewModel;
    SummaryViewModel _summaryViewModel;
    public ApplicationViewModel()
    { 
        //Add pages
        _homeViewModel = new HomeViewModel(this);
        _summaryViewModel = new SummaryViewModel();

        //some code here
        _homeViewModel.SomeProperty = 5;
        CurrentBasePageViewModel = _homeViewModel;
    }
}
public ApplicationViewModel()
{
    //shared model
    var model = new MyModel();

    //Add pages
    BasePageViewModels.Add("Home Page", new HomeViewModel(model));
    BasePageViewModels.Add("Summary Page", new SummaryViewModel(model));
    BasePageViewModels.Add("AddTestRun Page", new AddTestRunViewModel(model));

    //some code here
    CurrentBasePageViewModel = BasePageViewModels["Home Page"];
}



<UserControl x:Class="ApplicationView"
             xmlns:vm="clr-namespace:MyApp.ViewModels"
             xmlns:vw="clr-namespace:MyApp.Views">

    <UserControl.Resources>

        <DataTemplate DataType="{x:Type vm:HomeViewModel}">
            <vw:HomeView />
        </DataTemplate>

        <DataTemplate DataType="{x:Type vm:SummaryViewModel}">
            <vw:SummaryView />
        </DataTemplate>

        <DataTemplate DataType="{x:Type vm:AddTestRunViewModel}">
            <vw:AddTestRunView />
        </DataTemplate>

    </UserControl.Resources>

    <ContentControl Content={Binding CurrentBasePageViewModel} />

</UserControl>

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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