1

現在、ビュー コントロールをモデルに直接バインドしています。

しかし、私は次のことをしたいと思います: 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 が置き換えられた場合に発生します。

4

1 に答える 1