Diyan Bogdanov
Diyan Bogdanov

Reputation: 77

WPF How can i change ContentControl content

How can i change content control's content when button is clicked. For example i have content control with user control named "Home Page" when i clicked at some button i wanna change content control' content with another user control.

<Window ...
    xmlns:ViewModel="clr-namespace:PAL_PlayAndLearn.ViewModels"
    xmlns:Pages="clr-namespace:PAL_PlayAndLearn.Pages"
    ...>
<Window.DataContext>
    <ViewModel:AppViewModel />
</Window.DataContext>
    <Grid>
       <ContentControl Content="{Binding HomePage}"/>
    </Grid>
</Window>

Can you help me, because i don't have many time.

Upvotes: 4

Views: 13459

Answers (2)

Eric Ouellet
Eric Ouellet

Reputation: 11753

Sheridan answer is excellent but I give a full solution because I loose some time to put everything together. Hope it could help someone :-) ....

Please note than local:UserControlSpecialSignalTtrModel inherits from SignalProviderSpecial.

<UserControl
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
             xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
             xmlns:local="clr-namespace:ParametricStudyAnalysis.ScopeSelection.Special"
             xmlns:xcdg="http://schemas.xceed.com/wpf/xaml/datagrid" x:Class="ParametricStudyAnalysis.ScopeSelection.Special.UserControlAddSpecialSignal"
             mc:Ignorable="d" 
             d:DesignHeight="300" d:DesignWidth="300">
    <UserControl.DataContext>
        <local:UserControlAddSpecialSignalModel></local:UserControlAddSpecialSignalModel>
    </UserControl.DataContext>

    <UserControl.Resources>
        <DataTemplate DataType="{x:Type local:UserControlSpecialSignalTtrModel}">
            <local:UserControlSpecialSignalTtr/>
        </DataTemplate>     
    </UserControl.Resources>

    <Grid>
        <Grid.RowDefinitions>
            <RowDefinition Height="Auto"></RowDefinition>
            <RowDefinition></RowDefinition>
        </Grid.RowDefinitions>


        <GroupBox Header="Signal type" Grid.Row="0" Padding="5">
            <xcdg:DataGridControl Name="DataGrid" SelectionMode="Single" ItemsSource="{Binding SpecialSignalEntries}"
                              SelectedItem="{Binding SpecialSignalEntrySelected}" Height="200">
            <xcdg:DataGridControl.Columns>
                <xcdg:Column FieldName="Name" Title="Type of special signal" ReadOnly="True"></xcdg:Column>
            </xcdg:DataGridControl.Columns>
        </xcdg:DataGridControl>
        </GroupBox>

        <GroupBox Header="Parameters" Grid.Row="1" Margin="0,3,0,0" Padding="5">
            <ContentControl Name="MyContentControl" 
                            DataContext="{Binding SpecialSignalEntrySelected, Mode=OneWay}" 
                            Content="{Binding SignalProviderSpecial}">
            </ContentControl>
        </GroupBox>
    </Grid>
</UserControl>

Upvotes: 2

Sheridan
Sheridan

Reputation: 69985

You basically need one main, or parent view model. This view model should have a property of type BaseViewModel in it, let's say named ViewModel. All of your other page view models should extend this base class.

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

Now, because your view models all have a base type of BaseViewModel, they can all be set as the value for the ViewModel property... so to load a new view model, you set it as the value for this property:

ViewModel = new HomeView();

But how do we display the related views? Let's use DataTemplates to do that for us... add this and a similar entry for every view model that you will be using here:

<DataTemplate DataType="{x:Type ViewModels:HomeViewModel}">
    <Views:HomeView />
</DataTemplate>

Now WPF will render our views whenever we set the relating view model as the value for the ViewModel property. So finally, the Button? Well for that we need an ICommand in the main view model that is hooked to a Button in the main view and I recommend using the RelayCommand. Note that you'll need to alter your main view:

<Grid>
    <!-- Add your Buttons or Menu here, above where the views will be -->
    <ContentControl Content="{Binding HomePage}"/>
</Grid>

So, when a Button is clicked in the main view, you simply change the value of the ViewModel property and the DataTemplate will ensure that the relevant view is rendered in the UI. This is one of my own custom ICommand implementations like the RelayCommand that would load the view model if it wasn't already loaded:

public ICommand DisplayHomeView
{
    get { return new ActionCommand(action => ViewModel = new HomeViewModel(), 
        canExecute => !IsViewModelOfType<HomeViewModel>()); }
}

Upvotes: 6

Related Questions