WPF - 使用具有多个ViewModel的单个模型

时间:2015-10-07 08:55:49

标签: c# wpf mvvm

您如何允许多个视图模型共享同一模型?

我正在ApplicationViewModel中创建视图模型,该视图用于使用DataTemplate与所选VM在视图之间切换。

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"];
}

我希望能够从每个创建的VM中访问相同的Data类。 理想情况下,我会使用参数将Data类传递给每个ViewModel,但这会导致在XAML中设置DataContex会引发错误,因为DataContext没有可访问的构造函数。

更新

我在其他视图中设置DataContext,如下所示:

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

但这样做会创建ViewModel的新实例,而不是使用绑定到CurrentBasePageViewModel的实例。

3 个答案:

答案 0 :(得分:1)

Definitelly,解决方案是将模型传递给viemodel的构造函数。

现在,如何使用xaml解决您的问题?

首先,从你的问题和发布的代码来看,目前尚不清楚,问题是什么。 (缺少xaml代码)。

我只是猜测,问题是导致设计时datacontext,因为它需要无参数构造函数。有两种解决方案:

  1. 添加无参数构造函数:

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

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

    并在xaml中使用此类:

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

答案 1 :(得分:0)

尝试这样的事情:

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

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

然后,您的视图homeViewModel的某些int属性将具有值5。 您还可以在homeViewModel中创建属性,该属性将保存对当前ApplicationViewModel或create interface的引用。 界面示例:

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

然后使ApplicationViewModel实现此接口并将其传递给viewmodel。在viewModel中创建属性。类似的东西:

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

您的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;
    }
}

答案 2 :(得分:0)

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>