Window.Resources>
<DataTemplate x:Key="MainWindow" DataType="{x:Type viewModels:MergedModuleManagerViewModel}">
<ns:MainWindowView/>
</DataTemplate>
<DataTemplate x:Key="OpenProject" DataType="{x:Type viewModels:MergedModuleManagerViewModel}">
<ns:OpenProjectView/>
</DataTemplate>
</Window.Resources>
<Grid>
<ContentControl>
<ContentControl.Style>
<Style TargetType="{x:Type ContentControl}">
<Setter Property="ContentTemplate" Value="{DynamicResource MainWindow}" />
<Style.Triggers>
<DataTrigger Binding="{Binding SwitchView}" Value="1">
<Setter Property="ContentTemplate" Value="{DynamicResource MainWindow}" />
</DataTrigger>
<DataTrigger Binding="{Binding SwitchView}" Value="2">
<Setter Property="ContentTemplate" Value="{DynamicResource OpenProject}" />
</DataTrigger>
</Style.Triggers>
</Style>
</ContentControl.Style>
</ContentControl>
</Grid>
Например, так можно заменить один компонент на другой, соответственно, из кода меняется значение SwitchView - и соответственно его значению меняется отображаемый компонент. В некоторых частях приложения я делал проще, но не очень красиво - управлял видимостью конкретных компонентов, т.е. они располагаются в одном месте, и видим только один конкретный.
Используется MVVM, ViewModel должна реализовывать интерфейс INotifyPropertyChanged