【问题标题】:Multiple ViewModels in same View同一视图中的多个 ViewModel
【发布时间】:2020-01-14 04:05:57
【问题描述】:

我想在同一个视图 (MainPage.xaml) 中显示几个不同的 ViewModel。

我是新手,不知道该怎么做。我试图创建一个 MainViewModel:

    public class MainViewModel : ViewModelBase, INotifyPropertyChanged
    {
        WeatherViewModel weatherView = new WeatherViewModel();
        ForecastViewModel forecastViewModel = new ForecastViewModel();
        DeparturesViewModel departuresViewModel = new DeparturesViewModel();
        CalenderViewModel calenderViewModel = new CalenderViewModel();
    }

    public void GetAllViews()
    {
        weatherView.GetCurrentTemp();
        forecastViewModel.GetForecastTemp();
        departuresViewModel.GetDepartures();
        calenderViewModel.GetCalender();
    }

在我的 MainPage.xaml.cs 我有这个:

     public MainPage()
     {
        this.InitializeComponent();
        this.DataContext = new MainViewModel();
     }

     private void Window_Loaded(object sender, RoutedEventArgs e)
     {
        var vm = this.DataContext as MainViewModel;
        vm.GetAllViews();
     }

我设法像这样单独显示每个 ViewModel:

  this.DataContext = new WeatherViewModel();

但我想在同一个视图中显示所有内容。

【问题讨论】:

  • 您想将所有 ViewModel 数据显示到一个视图中?
  • 是的。这是不好的做法吗?我想同时显示所有数据。
  • 是的,这是不好的做法...您必须在一个 ViewModel 中收集所有数据并连接到 View... example.. ViewModel 包含模型形式的数据
  • 我有 4 个包含不同数据的不同 ViewModel。你建议我改用 1 ViewModel 吗?
  • 是的应该是一个 ViewModel 但你可以创建多个 Model

标签: c# mvvm view uwp viewmodel


【解决方案1】:

我认为你在正确的轨道上,但错过了一些小而重要的部分。

在您的示例代码中,MainViewModel 类当前设置有您真正需要公共属性的私有字段。此外,如果还没有,我会确保 ViewModelBase 实现INotifyPropertyChanged;这样,派生自 ViewModelBase 的任何类都无需担心该部分。

public abstract class ViewModelBase : INotifyPropertyChanged
{
    /* INotifyPropertyChanged implementation +
       whatever other common behavior makes sense
       belongs in this class
    */
}

public class MainViewModel : ViewModelBase
{
    public WeatherViewModel Weather { get; } = new WeatherViewModel();
    public ForecastViewModel Forecast { get; } = new ForecastViewModel();
    public DeparturesViewModel Departures { get; } = new DeparturesViewModel();
    public CalendarViewModel Calendar { get; } = new CalendarViewModel();
}

在您的视图代码隐藏文件中,您将数据上下文设置为 MainViewModel 的 2 个不同实例 - 一次在构造函数中,一次在 Loaded 事件处理程序中。我会坚持使用构造函数版本,或者您可以像这样在 XAML 中设置数据上下文:

<MainPage.DataContext>
    <MainViewModel>
</MainPage.DataContext>

一旦设置了主页的数据上下文并且视图模型是公共属性,那么您可以使用绑定来访问视图模型的状态(属性),可能是这样的:

<TextBlock Text='{Binding Path=Weather.CurrentTempCelsius, StringFormat='Current Temp: {0}°C'}' />

【讨论】:

    【解决方案2】:

    多个 ViewModel 在同一个视图中

    你有很多方法可以接近。拳头方式使用x:bind。您可以初始化页面资源中的每个视图模型并给它们x:Name,然后使用 x:bind 访问特定属性,如下所示。

    <Page.Resources>
        <local:CalenderViewModel x:Name="CalenderViewModel"/>
        <local:DeparturesViewModel x:Name="DeparturesViewModel"/>
        <local:ForecastViewModel x:Name="ForecastViewModel"/>
        <local:WeatherViewModel x:Name="WeatherViewModel"/>
    </Page.Resources>
    <Grid>
        <TextBlock Text="{x:Bind WeatherViewModel.temperature}"/>
    </Grid>
    

    其他方式是将所有 ViewModel 集成到 MainViewModel 中。 coding.monkey 提供了正确的解决方案,您可以直接参考。

    【讨论】:

    • 如果我想使用x:bind。我还需要在 MainPage.xaml.cs 中写 this.DataContext = new MainViewModel(); 吗?
    • 如果你写this.DataContext = new MainViewModel();,你可以使用Binding直接在xaml中访问MainViewModel的属性。对于这种情况,您还可以像上面一样使用 x:bind。
    • 这与@coding.monkey 结合使用。非常感谢! =)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2023-03-11
    • 2022-12-11
    • 1970-01-01
    • 1970-01-01
    • 2010-12-31
    • 1970-01-01
    • 2021-04-22
    相关资源
    最近更新 更多