Question

I'm interested in creating an app that displays some buttons and changes a viewport according to the selected button. The viewport in my app is a ContentControl and I thought of changing its content whenever a button is clicked. However, I believe there's a better approach, by perhaps injecting the ViewModels of each of the Views I want to present to the ContentControl and styling them using DataTemplates (Since I want to avoid having a grid with many controls and just setting their Visibility property whenever I want to show a particular view). Which of the approaches seems better to you? Do you have a different approach for this?

The view should be something similar to this: General application UI design

Thanks!

Was it helpful?

Solution

Usually have a ViewModel behind the window which contains:

  • ObservableCollection<IViewModel> AvailableViewModels
  • IViewModel SelectedViewModel
  • ICommand SetCurrentViewModelCommand

I display the AvailableViewModels using an ItemsControl, which has its ItemTemplate set to a Button. The Button.Command is bound to the SetCurrentViewModelCommand, and it passes the current data item from the AvailableViewModels collection in through the CommandParameter

To display the content area, I use a ContentControl with ContentControl.Content bound to SelectedViewModel, and DataTemplates get used to tell WPF how to render each ViewModel.

The end result is my XAML looks something like this:

<Window.Resources>
    <DataTemplate DataType="{x:Type local:ViewModelA}">
        <local:ViewA />
    </DataTemplate>
    <DataTemplate DataType="{x:Type local:ViewModelB}">
        <local:ViewB />
    </DataTemplate>
</Window.Resources>

<DockPanel>
    <Border DockPanel.Dock="Left" BorderBrush="Black" BorderThickness="0,0,1,0">
        <ItemsControl ItemsSource="{Binding AvailableViewModels}">
            <ItemsControl.ItemTemplate>
                <DataTemplate>
                    <Button Content="{Binding Name}"
                            Command="{Binding DataContext.SetCurrentViewModelCommand, RelativeSource={RelativeSource AncestorType={x:Type ItemsControl}}}"
                            CommandParameter="{Binding }"
                            Margin="2,5"/>
                </DataTemplate>
            </ItemsControl.ItemTemplate>
        </ItemsControl>
    </Border>

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

You can view an example of the full code used for such a setup on my blog

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top