目前我正在将我的View Control直接绑定到我的模型。
但我想: a)提供比模型中公开的事件/属性更多的事件/属性。 b)根据更适合视图的模型数据提供属性
为此,我决定在其间引入一个层,我称之为ViewModel(不确定这是否适用于术语ViewModel)
我的场景中ViewModel的工作是订阅模型公开的所有事件,并使用这些事件来修改ViewModel中的依赖项属性。
我这样做了如下。
<ItemsControl ItemsSource="{Binding Items}">
<ItemsControl.ItemTemplate>
<DataTemplate>
<local:View DataContext="{Binding Converter={StaticResource modelToViewModel}}"/>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
此处,Items是“模型”类型数据的集合,我将其转换为视图可以绑定到的“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中属性更改的事件。我认为最好的地方就是View的卸载事件,但是想要你的想法。
public partial class View : UserControl
{
public View()
{
Unloaded += OnUnloaded;
InitializeComponent();
}
void OnUnloaded(object sender, RoutedEventArgs e)
{
if (DataContext != null)
{
(DataContext as ViewModel).Dispose();
}
}
}
编辑:我想我还需要在视图的datacontext发生更改时调用dispose,如果替换了Items列表中的Item,就会发生这种情况。
答案 0 :(得分:0)
你可以实现IDisposable。
public class ViewModel : DependencyObject, IDisposable
{
public Model Model { get; private set; }
public ViewModel(Model _model)
{
Model = _model;
Model.PropertyChanged += OnModelPropertyChanged;
}
~ViewModel()
{
Dispose(false);
}
void OnModelPropertyChanged(object sender, PropertyChangedEventArgs e)
{
// .. here - I would modify this ViewModels dependency properties
}
public void Dispose()
{
Dispose(true);
GC.SupressFinalize();
}
protected virtual void Dispose(bool disposing)
{
if (disposing)
{
if (Model != null)
Model.PropertyChanged -= OnModelPropertyChanged;
}
}
}
如果您对实施感到疑惑。您可以找到一些信息here。您还必须在视图中分配回调。
public partial class View : UserControl
{
public View()
{
Unloaded += OnUnloaded;
InitializeComponent();
}
void OnUnloaded(object sender, RoutedEventArgs e)
{
if (DataContext != null)
{
(DataContext as ViewModel).Dispose();
}
Unloaded -= OnUnloaded; // <---
}
}