WPFアプリケーションで同一領域内に複数のビューを動的に表示する際、TabControlのカスタマイズが必要になるケースがあります。代わりにContentControlを活用し、ボタン操作でコンテンツを切り替えるシンプルな実装方法を紹介します。
<UserControl x:Class="SampleApp.Views.DashboardView"
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:SampleApp.Views"
mc:Ignorable="d"
d:DesignHeight="450" d:DesignWidth="800">
<Grid>
<TextBlock Text="{Binding ScreenTitle}" FontSize="50"
HorizontalAlignment="Center" VerticalAlignment="Center"/>
</Grid>
</UserControl>using System.ComponentModel;
using System.Runtime.CompilerServices;
namespace SampleApp.ViewModels
{
public class DashboardViewModel : INotifyPropertyChanged
{
public DashboardViewModel() => ScreenTitle = "ダッシュボード";
private string screenTitle;
public string ScreenTitle
{
get => screenTitle;
set
{
screenTitle = value;
OnPropertyChanged();
}
}
public event PropertyChangedEventHandler PropertyChanged;
protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null) =>
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
}<UserControl x:Class="SampleApp.Views.SettingsView"
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:SampleApp.Views"
mc:Ignorable="d"
d:DesignHeight="450" d:DesignWidth="800">
<Grid>
<TextBlock Text="{Binding ScreenTitle}" FontSize="50"
HorizontalAlignment="Center" VerticalAlignment="Center"/>
</Grid>
</UserControl>using System.ComponentModel;
using System.Runtime.CompilerServices;
namespace SampleApp.ViewModels
{
public class SettingsViewModel : INotifyPropertyChanged
{
public SettingsViewModel() => ScreenTitle = "設定画面";
private string screenTitle;
public string ScreenTitle
{
get => screenTitle;
set
{
screenTitle = value;
OnPropertyChanged();
}
}
public event PropertyChangedEventHandler PropertyChanged;
protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null) =>
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
}<Window x:Class="SampleApp.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:views="clr-namespace:SampleApp.Views"
mc:Ignorable="d"
Title="メインウィンドウ" Height="450" Width="800">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition/>
</Grid.ColumnDefinitions>
<StackPanel Margin="10">
<Button x:Name="dashboardButton" Content="ダッシュボード" Click="SwitchToDashboard"
Height="40" Width="120" Margin="5"/>
<Button x:Name="settingsButton" Content="設定" Click="SwitchToSettings"
Height="40" Width="120" Margin="5"/>
</StackPanel>
<ContentControl x:Name="contentHost" Grid.Column="1"/>
</Grid>
</Window>using System.Collections.Generic;
using System.Windows;
namespace SampleApp
{
public partial class MainWindow : Window
{
private readonly Dictionary<string, UserControl> viewPool = new Dictionary<string, UserControl>();
public MainWindow()
{
InitializeComponent();
viewPool["dashboard"] = new DashboardView { DataContext = new DashboardViewModel() };
viewPool["settings"] = new SettingsView { DataContext = new SettingsViewModel() };
}
private void SwitchToDashboard(object sender, RoutedEventArgs e) =>
contentHost.Content = viewPool["dashboard"];
private void SwitchToSettings(object sender, RoutedEventArgs e) =>
contentHost.Content = viewPool["settings"];
}
}