現在、ビュー コントロールをモデルに直接バインドしています。
しかし、私は次のことをしたいと思います: a) モデルで公開されているものよりも多くのイベント/プロパティを提供します。b) ビューにより適したモデル データに基づくプロパティを提供する
これを行うために、間にレイヤーを導入することにしました。これを ViewModel と呼んでいます (これが ViewModel という用語の正しい使用法であるかどうかはわかりません)。
私のシナリオでのビューモデルの作業は、モデルによって公開されたすべてのイベントをサブスクライブし、それらのイベントを使用してビューモデルの依存関係プロパティを変更することです。
私はこれを次のようにしました。
<ItemsControl ItemsSource="{Binding Items}">
<ItemsControl.ItemTemplate>
<DataTemplate>
<local:View DataContext="{Binding Converter={StaticResource modelToViewModel}}"/>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
ここで、Items は「Model」タイプのデータのコレクションであり、ビューをバインドできる「ViewModel」タイプに変換します。
public class Model : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
int m_age;
public int Age
{
get { return m_age; }
set { m_age = value; NotifyPropertyChanged("Age"); }
}
void NotifyPropertyChanged(string _property)
{
if (PropertyChanged != null)
{
PropertyChanged(this, new PropertyChangedEventArgs(_property));
}
}
}
public class ViewModel : DependencyObject
{
public Model Model { get; private set; }
public ViewModel(Model _model)
{
Model = _model;
Model.PropertyChanged += OnModelPropertyChanged;
}
void OnModelPropertyChanged(object sender, PropertyChangedEventArgs e)
{
// .. here - I would modify this ViewModels dependency properties
}
}
public class ModelToViewModel : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
return new ViewModel(value as Model);
}
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
throw new NotImplementedException();
}
}
私が今抱えている問題は、ViewModel のプロパティ変更イベントを登録解除できるように、ViewModel を破棄する方法です。これを行うのに最適な場所は、ビューのアンロード イベントであると考えていますが、ご意見をお聞かせください。
public partial class View : UserControl
{
public View()
{
Unloaded += OnUnloaded;
InitializeComponent();
}
void OnUnloaded(object sender, RoutedEventArgs e)
{
if (DataContext != null)
{
(DataContext as ViewModel).Dispose();
}
}
}
編集: ビューのデータコンテキストが変更されたときに dispose を呼び出す必要があると思います。これは、Items リスト内の Item が置き換えられた場合に発生します。