Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to display different views on MainWindow

Tags:

mvvm

wpf

So I followed a video online that showed me how to implement MVVM in a WPF application. Please note that I am a newbie when it comes to both of them.

I have the following classes that comprise the Model, View, and ViewModel layers of my WPF application:

  • App class (.xaml and .xaml.cs)
  • MainWindow class (.xaml and .xaml.cs)
  • MainWindowViewModel.cs
  • MalfunctionsView (.xaml and .cs)
  • MalfunctionsViewModel.cs
  • PartsView (.xaml and .cs)
  • PartsViewModel.cs

Basically I just have two views (Malfunctions and Parts) that get loaded up into the MainWindow view.

I have it setup right now so that I can comment code in and out to show either the MalfunctionView or the PartsView in the MainWindow. For example, if I want to see the MalfunctionView then I comment out all of the PartsView code and then re-run it in VS. Yes, I know... it's sad and pathetic, but I haven't learned how to unload one view and load another view on the fly. Which brings me to my question: how do I unload one view from the MainWindow and then load up a different view into the MainWindow? For example, I have a button on the PartsView called Select, which when clicked then needs to unload the PartsView from the MainWindow and load up the MalfunctionsView in it's place.

I am including the code that I have for the App class and MainWindow View and MainWindow ViewModel so that it can be seen how I am currently loading up ViewModels (user controls) into the MainWindow.

App.xaml.cs

public partial class App : Application {
        protected override void OnStartup(StartupEventArgs e) {
            base.OnStartup(e);

            // Create MainWindow ViewModel
            var mainWindowVM = new MainWindowVM();

            // Create MainWindow View
            MainWindow mainWindowVw = new MainWindow();

            // Set MainWindow View datacontext to MainWindow ViewModel and then show the window
            mainWindowVw.DataContext = mainWindowVM;
            mainWindowVw.Show();   
        }
    }

MainWindow.xaml

<Window x:Class="PAM.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:vm="clr-namespace:PAM.ViewModel"
        xmlns:vw="clr-namespace:PAM.View"
        Title="Parts and Malfunctions" Height="800" Width="550">

    <Window.Resources>
        <DataTemplate DataType="{x:Type vm:MalfunctionsViewModel}">
            <vw:MalfunctionsView />
        </DataTemplate>
        <DataTemplate DataType="{x:Type vm:PartsViewModel}">
            <vw:PartsView />
        </DataTemplate>
    </Window.Resources>

    <Grid Width="Auto" Height="Auto">
        <ScrollViewer>
            <ItemsControl Width="Auto" Height="Auto" ItemsSource="{Binding ViewModels}"></ItemsControl>
        </ScrollViewer>
    </Grid>
</Window>

MainWindowViewModel.cs

public class MainWindowViewModel : ViewModelBase {

        readonly MalfunctionRepository _mfRepo;
        //readonly PartsRepository _pRepo;

        ObservableCollection<ViewModelBase> _viewModels;

        public ObservableCollection<ViewModelBase> ViewModels {
            get {
                if (_viewModels == null)
                    _viewModels = new ObservableCollection<ViewModelBase>();

                return _viewModels;
            }
        }

        public MainWindowViewModel() {

            // ================================
            // Malfunctions ViewModel
            _mfRepo = new MalfunctionRepository();

            MalfunctionsViewModel viewModel = new MalfunctionsViewModel(_mfRepo);

            // ================================
            // Parts ViewModel
            //_pRepo = new PartsRepository();

            //PartsViewModel viewModel = new PartsViewModel(_pRepo);

            this.ViewModels.Add(viewModel);
        }
    }
like image 253
Jagd Avatar asked Sep 11 '25 10:09

Jagd


1 Answers

In your MainWindow.xaml:

<ContentControl Content="{Binding Content}" />

In your ViewModel:

private object content;
public object Content
{
    get { return content; }
    set
{
    content = value; 
    NotifyPropertyChanged(p => p.Content);
}       

...

MalfunctionsViewModel mvm = new MalfunctionsViewModel(_mfRepo);
Content = mvm;

...

PartsViewModel pvm = new PartsViewModel(_pRepo);
Content = pvm;

Check out the very similar question I asked a few years back: WPF MVVM: How to load views "on demand" without using plug-in architecture?

like image 75
Dean Kuga Avatar answered Sep 13 '25 06:09

Dean Kuga