再利用したいものが 2 つあります。
- MessageViewModel のコレクションを公開して、このコレクションを ListView の itemsSource にバインドできるようにします。
- (オプション) 特定のリスト ビューに、再利用したいスタイル (またはコンテンツ プレゼンター、またはデータ テンプレート) があります。この部分には、コード ビハインド、トリガーなどが含まれる場合もあります。
2 つを混ぜてはいけません。
#2 は、リスト ビューまたはデータ テンプレートに適用するスタイルで実現できます。個人的には、専用のクラスを MessageViewModel のコレクションとして定義し、データ テンプレートで TargetType をそのクラスに設定するのが好きです。
#1 は Collection、INotifyCollecitonChanged、INotifyPropertyChanged を実装するクラスです。最善の (そして最も簡単な) 方法は、単に ObservableCollection をラップすることです。構築では、Select メソッドを実行します。次に、簿記の方法があります。
いくつかのサンプル(動作中!)コードの下。ビューにはコードビハインドがないことに注意してください。2 つのリストをグリッドに 2 回配置しました。ContentControl と DataTemplate の使用は私のスタイルです。これを行う方法は他にもたくさんあります。
======= Model.cs ====
using System;
namespace SO
{
class Message
{
public string from { get; set; }
public string to { get; set; }
public string subject { get; set; }
public DateTime received { get; set; }
}
}
======= ViewModel.cs ====
using System;
using System.Collections.Generic;
using System.Linq;
using System.Collections.ObjectModel;
using System.ComponentModel;
namespace SO
{
class MessageVM : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
private Message m_model;
public MessageVM( Message model ) {
m_model = model;
}
private void raize( string prop ) {
PropertyChanged( this, new PropertyChangedEventArgs("prop") );
}
public string from {
get { return m_model.from; }
set { m_model.from = value; raize("from"); }
}
public string to {
get { return m_model.to; }
set { m_model.subject = value; raize("to") ); }
}
public string subject {
get { return m_model.subject; }
set { m_model.subject = value; raize("subject") ); }
}
public DateTime received {
get { return m_model.received; }
set { m_model.received = value; raize("recieved") ); }
}
}
class FolderVM : ObservableCollection<MessageVM>
{
public FolderVM( IEnumerable<Message> models )
:base( models.Select( msg => new MessageVM(msg) ) )
{
}
}
class SampleData
{
//static public FolderVM folder { get; set; }
static public FolderVM folder;
static SampleData( )
{
// create a sample model
List<Message> model = new List<Message>();
model.Add( new Message { from = "Bill", to = "Steve", subject = "Resusable Items Control", received = DateTime.Now.AddDays(-4) } );
model.Add( new Message { from = "Steve", to = "Bill", subject = "Resusable Items Control", received = DateTime.Now.AddDays( -3 ) } );
model.Add( new Message { from = "Bill", to = "Jeff", subject = "stack", received = DateTime.Now.AddDays( -2 ) } );
// initialize the view model
folder = new FolderVM( model );
}
}
}
======= MainWindow.xaml ====
<Window x:Class="Paf.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:src="clr-namespace:SO"
Title="MainWindow" Height="350" Width="525"
>
<Window.Resources>
<DataTemplate DataType="{x:Type src:FolderVM}">
<ListView ItemsSource="{Binding}">
<ListView.View>
<GridView>
<GridViewColumn Header="from" Width="80" DisplayMemberBinding="{Binding Path=from}" />
<GridViewColumn Header="to" Width="80" DisplayMemberBinding="{Binding Path=to}" />
<GridViewColumn Header="subject" Width="200" DisplayMemberBinding="{Binding Path=subject}" />
<GridViewColumn Header="received" Width="160" DisplayMemberBinding="{Binding Path=received}" />
</GridView>
</ListView.View>
</ListView>
</DataTemplate>
</Window.Resources>
<StackPanel>
<ContentControl Content="{Binding Source={x:Static src:SampleData.folder}}" />
<ContentControl Content="{Binding Source={x:Static src:SampleData.folder}}" />
</StackPanel>
</Window>