Sonhja
Sonhja

Reputation: 8458

WPF Change between controls

I have a simple application where I have a main screen with some operations, and a second screen that you access when first one is done and you press a button. See image:

enter image description here

Brown areas are fixed left menus, that will always appear in the same location. Blue areas are the screens that change from one to another. Red area is trying to simulate a MDIContainer from WindowsForms.

How can I simulate that container to:

  1. Mantain the left static menu

  2. Change dynamically my content due to some events/actions?

Upvotes: 4

Views: 3191

Answers (2)

paparazzo
paparazzo

Reputation: 45096

<Grid>
    <Grid.ColumnDefinitions>
        <ColumnDefinition Width="*"/>
        <ColumnDefinition Width="2*"/>
    </Grid.ColumnDefinitions>
    <Grid.RowDefinitions>
        <RowDefinition Height="*"/>
    </Grid.RowDefinitions>
    <TextBlock Grid.Row="0" Grid.Column="0" Text="Static"/>
    <ContentControl x:Name="content1" Grid.Row="0" Grid.Column="1" Visibility="Visible" >
        <StackPanel>
            <TextBlock Text="One" />
            <Button Click="btn1_click" Content="Button1"/>
        </StackPanel>
    </ContentControl>
    <ContentControl x:Name="content2" Grid.Row="0" Grid.Column="1" Visibility="Hidden" >
        <StackPanel>
            <TextBlock Text="Two" />
            <Button Click="btn2_click" Content="Button2"/>
        </StackPanel>
    </ContentControl>
</Grid>

        private void btn1_click(object sender, RoutedEventArgs e)
        {
            content1.Visibility = System.Windows.Visibility.Hidden;
            content2.Visibility = System.Windows.Visibility.Visible;
        }

        private void btn2_click(object sender, RoutedEventArgs e)
        {
            content1.Visibility = System.Windows.Visibility.Visible;
            content2.Visibility = System.Windows.Visibility.Hidden;
        }

If you can put the button above like in a menu area
Can do me dynamic stuff with Frame and Page content
This example shows passing data to the Page constructor
nextPage is a Page
could also be a UserControl

<Frame Name="SrchItemEditField" />

PageDocFieldDetail nextPage = new PageDocFieldDetail(df);
SrchItemEditField.Content = nextPage;

Upvotes: 2

Daniel
Daniel

Reputation: 11064

The best way would be first to use a grid control to lay out the controls (as Blam suggested) like so:

<Grid>
    <Grid.ColumnDefinitions>
        <ColumnDefinition Width="Auto"/>
        <ColumnDefinition Width="*"/>
    </Grid.ColumnDefinitions>

    <!-- Menu control. (Whichever you see fit. The menu could be established 
         within this control, or you could use a custom UserControl depending
         on your needs.) -->
    <StackPanel />

    <!-- Content control -->
    <ContentPresenter Name="ContentHolder" 
                      Grid.Column="1" />
</Grid>

Depending on your design pattern, there are a couple of ways to get your content to appear as desired.

If you are using MVVM, the ContentPresenter control could be bound to a ViewModel in the data context of your main window, like so:

    <ContentPresenter Name="ContentHolder" 
                      Grid.Column="1"
                      Content="{Binding ContentData}" /> 

And a corresponding property would exist in your ViewModel, such as:

    public ViewModelBase ContentData{
      get { return _contentData; }
    }

If that's a lot of Greek to you, you are probably not using MVVM as your design pattern. In that case, the code behind of your main window class could handle setting the content of the ContentPresenter with an event handler.

The gist of your event handler could be something like this:

    public void HandleNavigationChange(SwitchCondition sc){
      UserControl newContent = null;

      switch (sc) {
        case SwitchCondition.NavigationItem1:
          newContent = new NavigationItem1();
          break;

        case SwitchCondition.NavigationItem1:
          newContent = new NavigationItem1();
          break;
        //ETC
      }

      ContentHolder.Content = newContent;
    }

You could then call this method from menu item clicks, or if you like, from children controls.

Upvotes: 3

Related Questions