-1

I have a Window with four Buttons to Add, Search, Delete and Update Database Querys.

After clicking one of these Buttons, I open a new Window with specific WPF Controls for these function.

How can I do this without open a new Window? Everything should happen in one Window, only the WPF Controls should Change and the Code behind. After clicking "Back" or "Execute" I want to go back to the Main Window.

Andrew Barber
  • 39,603
  • 20
  • 94
  • 123
slopsucker
  • 125
  • 2
  • 9

3 Answers3

7

The key is ContentControl - you will be changing its Content:

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

and in your view model you will have property object WhatToShow.

if(some_condition) 
  WhatToShow = new SomeView(someViewModel);
else
  WhatToShow = new AnotherView(anotherViewModel);

Or you can look at Caliburn.Micro, a MVVM framework that makes screen navigation easier.

Karel Frajták
  • 4,389
  • 1
  • 23
  • 34
  • Sorry for the newbie Question, but my knowledge stops at Classes and DataBinding. What is my View Model? – slopsucker Jan 21 '12 at 12:01
  • view model know nothing about view. So, operation WhatToShow = new SomeView(someViewModel) in viewmodel doesn't correspond to MVVM. You need to operate only with view models. – Vladimir Dorokhov Jan 21 '12 at 13:34
  • 1
    Don't forget to add a DataTemplate for the type of the object WhatToShow into the resources. – Maurizio Reginelli Jan 21 '12 at 13:38
  • Vladimir, you're right, this is not pure MVVM, I just wanted to demonstrate how the ContentControl.Content can be changed. With DataTemplate as Maurizio is pointing out it is much cleaner, only view models will be pushed into WhatToShow property. – Karel Frajták Jan 21 '12 at 13:47
1

I'd recoment the next approach:

  1. put TabControl onto your view - the TabControl will be used for switching between different views
  2. apply style for the TabControl that hides tab headers (how to hide tab control headers?)
  3. prepare view model for every view which will be switching, e.g., ViewModel1, ViewModel2.
  4. prepare main view model that aggregates all switching view models, e.g.

     public class MainViewModel : INotifyPropertyChanged
    
        {
    
             private ViewModel1 _viewModel1 = new ViewModel1();
    
             private ViewModel2 _viewModel2 = new ViewModel2();
    
             private INotifyPropertyChanged _currentViewModel;
             public INotifyPropertyChanged CurrentViewModel
             {
                 get { return _currentViewModel; }
                 set
                 {
                     _currentViewModel = value;
                     RaisePropertyChanged(() => CurrentViewModel);
                 }
              }
    
                public IEnumerable<INotifyPropertyChanged> ViewModelsToSwitch
                {
                    get
                    {
                        return new INotifyPropertyChanged[]
                                   {
                                       _viewModel1,
                                       _viewModel2
                                   };
                    }
                }
    
            // INotifyPropertyChanged implementation
    

    }

  5. bind MainViewModel to the TabControl:

 <Window x:Class="SwitchViewDemo.MainWindow"
            xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
            xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
            Title="MainWindow" Height="350" Width="525">
        <Grid>
            <TabControl ItemsSource="{Binding ViewModelsToSwitch}"
                        SelectedItem="{Binding CurrentViewModel}"/>
        </Grid>
    </Window>

6 . declare view for each view model:

<Window x:Class="WpfApplication4.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="MainWindow" Height="350" Width="525">
    <Window.Resources>
        <DataTemplate DataType="{x:Type ViewModel1}">
            <TextBlock Text="View 1"/>
        </DataTemplate>
        <DataTemplate DataType="{x:Type ViewModel2}">
            <TextBlock Text="View 2"/>
        </DataTemplate>
    </Window.Resources>
    <Grid>
        <TabControl ItemsSource="{Binding ViewModelsToSwitch}"
                    SelectedItem="{Binding CurrentViewModel}"/>
    </Grid>
</Window>

7 . set in MainViewModel CurrentViewModel to ViewModel1 or ViewModel2 and associated with this view model view will be displayed.

Benefits:

  • corresponds to the MVVM pattern - so you get all MVVM benefits
  • good scaling. If you want to add new ViewModel3 you need just add this view model to main view model and create addional DataTemplate that declares mapping of the view model on specified view.
Community
  • 1
  • 1
Vladimir Dorokhov
  • 3,784
  • 2
  • 23
  • 26
0

Instead of a Window, create a grid for each operation. And within that grid put its specific controls. Set the Visibility of all the grid to Visibility.Collapsed. When someone presses one of the buttons, set the relevant grid's Visibility to Visibility.Visible and the other to collapsed. Having said that, it is more organized to use UserControls, which are very easy to use. Just add your XAML there and include it in your main window. Then hide and show as I said previously.

Lzh
  • 3,585
  • 1
  • 22
  • 36
  • This was my first plan too, but after 3 or 4 masks, i dont think this is well organized having so much Grids in a XAML and Hide or Show it. The Method which Karel said impress me, but i dont know how implement that. – slopsucker Jan 21 '12 at 12:10