简体   繁体   中英

Multiple ViewModels in same View

I have several different ViewModels that I would like to display in the same view (MainPage.xaml).

I'm new to this and don't know how to do it. I have tried to create a 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();
    }

And in my MainPage.xaml.cs I have this:

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

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

I manage to display each ViewModel individually like this instead:

  this.DataContext = new WeatherViewModel();

but I would like to display everything in the same View.

I think you're on the right track but missed some small but important pieces.

In your example code the MainViewModel class is currently setup with private fields where you really need public properties. Additionally, I would make sure ViewModelBase implements INotifyPropertyChanged if it's not already; that way none of the classes deriving from ViewModelBase need to worry about that part.

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();
}

In your view code behind file you're setting the data context to 2 different instances of MainViewModel - once in the constructor and once in the Loaded event handler. I'd stick with the constructor version or instead you could set the data context in XAML like this:

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

Once the data context for the main page is setup and the view models are public properties then you can use bindings to access the state (properties) of the view models perhaps something like this:

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

Multiple ViewModels in same View

You have many ways to approach. Fist way using x:bind . You could initialize each view model in the page resource and give them x:Name , then using x:bind to access specific property like following.

<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>

Other Way is that integrate all the ViewModels into MainViewModel . And coding.monkey provide the correct solution that you could refer directly.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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