3

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:

bagz_man
  • 555
  • 2
  • 8
  • 20
  • 1
    You can use a `ContentPresenter` and change the content as per the selected option – sa_ddam213 Aug 30 '13 at 02:04
  • You can simply put any View/XAML as the Content. A number of the MVVM frameworks (I use ReactiveUI) have powerful select a ViewModel and View is found switching containers. EDIT: take a look here http://stackoverflow.com/questions/15353500/contentcontrol-not-updating – kenny Aug 30 '13 at 02:08
  • Care to give the explanation? Maybe in the new answer. – bagz_man Sep 02 '13 at 04:13

3 Answers3

4

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

Community
  • 1
  • 1
Federico Berasategui
  • 43,562
  • 11
  • 100
  • 154
  • Definitely could be accepted.. Anyway, I'm still waiting for another approach..Maybe with ContentPresenter/ContentControl – bagz_man Sep 02 '13 at 04:12
  • @bagz_man the `TabControl` default template already contains a `ContentPresenter`. Why would you want to reinvent the wheel?. Also, what's wrong with my approach? – Federico Berasategui Sep 02 '13 at 16:12
  • your approach is very good indeed and I'm +1 ing it. I'm just thinking about another approach using ContentControl along with ContentPresenter. Because I think we can separate the OPTION with the CONTENT, I mean there is some space between them and being more flexible. But if you could give the example for adding space between tabstrip and the content, it would be nice. – bagz_man Sep 03 '13 at 06:37
4

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!

bas
  • 13,550
  • 20
  • 69
  • 146
1

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.

Sheridan
  • 68,826
  • 24
  • 143
  • 183
  • No, I don't mean it as a tabbed container, because what I'm about to achieve is just one (and only one) container showing dynamic content. – bagz_man Aug 30 '13 at 11:42