for WPF developers
Home Profile Tips 全記事一覧

ViewModel のコレクションを ItemsSource プロパティに指定する

(2017/06/29 7:43:52 created.)

ここでは、TabControl コントロールで切り替えるコンテンツに対する ViewModel を次のように定義します。

ContentViewModel.cs
  1. namespace Tips_TabControl.ViewModels
  2. {
  3.     public class ContentViewModel : NotificationObject
  4.     {
  5.         /// <summary>
  6.         /// 新しいインスタンスを生成します。
  7.         /// </summary>
  8.         /// <param name="title">タイトルを指定します。</param>
  9.         public ContentViewModel(string title)
  10.         {
  11.             this.Title = title;
  12.         }
  13.  
  14.         private string _title;
  15.         /// <summary>
  16.         /// タイトルを取得します。
  17.         /// </summary>
  18.         public string Title
  19.         {
  20.             get { return this._title; }
  21.             private set { SetProperty(ref this._title, value); }
  22.         }
  23.     }
  24. }

Title プロパティを持ち、インスタンス生成時に必ず指定するようなクラスになっています。

続いて、このクラスをコレクションとして持つ MainViewModel を定義します。

MainViewModel.cs
  1. namespace Tips_TabControl.ViewModels
  2. {
  3.     using System.Collections.ObjectModel;
  4.  
  5.     public class MainViewModel : NotificationObject
  6.     {
  7.         /// <summary>
  8.         /// 新しいインスタンスを生成します。
  9.         /// </summary>
  10.         public MainViewModel()
  11.         {
  12.             this.Contents.Add(new ContentViewModel("Item1"));
  13.             this.Contents.Add(new ContentViewModel("Item2"));
  14.             this.Contents.Add(new ContentViewModel("Item3"));
  15.         }
  16.  
  17.         private ObservableCollection<ContentViewModel> _contents = new ObservableCollection<ContentViewModel>();
  18.         /// <summary>
  19.         /// コンテンツのコレクションを取得します。
  20.         /// </summary>
  21.         public ObservableCollection<ContentViewModel> Contents
  22.         {
  23.             get { return this._contents; }
  24.         }
  25.     }
  26. }

これで準備が整ったので、View の XAML コードを記述してみます。

MainView.xaml
  1. <Window x:Class="Tips_TabControl.Views.MainView"
  2.         xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
  3.         xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
  4.         Title="MainView" Height="300" Width="300">
  5.     <TabControl ItemsSource="{Binding Contents}" />
  6. </Window>


お察しの通り、ただ ItemsSource を指定するだけでは足りません。TabControl にはヘッダ部を変更する ItemTemplate プロパティと、コンテンツ部を変更する ContentTemplate プロパティがあるので、これらを適切に指定します。

MainView.xaml
  1. <Window x:Class="Tips_TabControl.Views.MainView"
  2.         xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
  3.         xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
  4.         Title="MainView" Height="300" Width="300">
  5.     <TabControl ItemsSource="{Binding Contents}" SelectedIndex="0">
  6.         <TabControl.ItemTemplate>
  7.             <DataTemplate>
  8.                 <TextBlock Text="{Binding Title}" />
  9.             </DataTemplate>
  10.         </TabControl.ItemTemplate>
  11.         <TabControl.ContentTemplate>
  12.             <DataTemplate>
  13.                 <TextBlock Text="{Binding Title, StringFormat={}これは{0}のコンテンツです}" />
  14.             </DataTemplate>
  15.         </TabControl.ContentTemplate>
  16.     </TabControl>
  17. </Window>


TabControl の ItemsSource プロパティに ContentViewModel のコレクションを指定しているため、個々のアイテムの DataContext は ContentViewModel になります。したがって、Title プロパティとデータバインディングすることで、ContentViewModel の Title プロパティが参照されるようになります。