WPF : dynamic view/content

I'm a bit beginner in WPF, so I ask this..

Let's say I have a window, and inside the window I want to have something like container, could be just border or maybe panel (in winform terms). The content of container is binded to the selected option (e.g:button). So, for instance, when user selects OPTION 1, the container shows chart; when user selects OPTION 2, the container shows listview filled with data; when user selects OPTION 3, the container shows another things, and so on.

What is the best/nicest (or easiest maybe) approach to do this? I'm thinking about using user control for the content of the container, but don't know if this is nice solution neither the performance for using user control to show little bit complex things and maybe some calculations. Any other idea guys?

illustration:


Solution 1:

To elaborate on @Sheridan's answer, here is a simple TabControl XAML that does what you need:

<TabControl TabStripPlacement="Left">

        <TabItem Header="Option 1">
            <Grid Background="DarkGray">
                <TextBlock Foreground="AliceBlue" VerticalAlignment="Center" HorizontalAlignment="Center" FontSize="20" Text="View 1"/>
            </Grid>
        </TabItem>

        <TabItem Header="Option 2">
            <Grid Background="DarkBlue">
                <TextBlock Foreground="AliceBlue" VerticalAlignment="Center" HorizontalAlignment="Center" FontSize="20" Text="View 2"/>
            </Grid>
        </TabItem>

        <TabItem Header="Option 3">
            <Grid Background="DarkSlateBlue">
                <TextBlock Foreground="AliceBlue" VerticalAlignment="Center" HorizontalAlignment="Center" FontSize="20" Text="View 3"/>
            </Grid>
        </TabItem>

    </TabControl>

Result:

enter image description here

You can customize it a little bit by adding this simple Style To your Window.Resources:

 <Window.Resources>
        <Style TargetType="TabItem">
            <Setter Property="Template">
                <Setter.Value>
                    <ControlTemplate TargetType="TabItem">
                        <RadioButton Content="{TemplateBinding Header}" Margin="2"
                                     IsChecked="{Binding IsSelected, RelativeSource={RelativeSource TemplatedParent}, Mode=TwoWay}"/>
                    </ControlTemplate>
                </Setter.Value>
            </Setter>
        </Style>
    </Window.Resources>

Which then results in:

enter image description here

The "WPF Mentality" makes you think the UI controls in terms of their functionality, not their appearance, this is a TabControl =)

Solution 2:

I solved this with a ContentControl

MainWindow: (Define the views you wish to visualize as resources)

<Window.Resources>
    <DataTemplate DataType="{x:Type viewModels:SystemPCViewModel}">
        <controls:SystemPCControl/>
    </DataTemplate>
    <DataTemplate DataType="{x:Type viewModels:ChipPCViewModel}">
        <controls:ChipPCControl/>
    </DataTemplate>
    </ResourceDictionary>

</Window.Resources>

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

ViewModel: (can't get much simpler)

public ViewModelBase CurrentView
{
    get { return currentView; }
    set { Set(() => CurrentView, ref currentView, value); }
}

And there you go, you can change your views by setting the view model for the controls you defined in your MainWindow

private void OnCommandExecuted()
{
    CurrentView = someViewModel;
}

private void OnAnotherCommandExecuted()
{
    CurrentView = anotherViewModel;
}

HTH!

Solution 3:

What you are describing sounds pretty close to a standard TabControl, but with a ControlTemplate that puts the tabs on the left side instead of above the content panel. Using this method would mean having a UserControl in each TabItem, eg. multiple controls. You can find out more about the TabControl from the TabControl Class page at MSDN.