我刚刚认识到,每次我使用MVVM并尝试用它的View显示ViewModel时,都会创建一个View实例,尽管我只是使用相同的ViewModel。
在我的视图中是GridView。我在后面的代码中写了这个,用来调用ViewModel的事件。
private void gridView_SelectionChanged(object sender, SelectionChangeEventArgs e)
{
DataContext.CallOnClick((DataContext as IHasSelectedItem<IViewModel>)?.SelectedItem);
}
问题是,如果我在视图的代码隐藏中定义了一些事件,我会多次获得这些事件,因为视图的实例总是被创建的,每个实例都会向ViewModel发送事件。
有人也有这个问题吗。或者有人知道解决方案?非常感谢!
-----------------------------------------------------------
添加:我已经这样更改了我的代码。它起作用了,我只参加过一次活动。但我不确定其他观点是否得到了处理
public TestView()
{
InitializeComponent();
IsVisibleChanged += TestView_IsVisibleChanged;
}
private void TestView_IsVisibleChanged(object sender, System.Windows.DependencyPropertyChangedEventArgs e)
{
if (e.NewValue.Equals(false))
{
MyGridView.SelectionChanged -= gridView_SelectionChanged;
}
else
{
MyGridView.SelectionChanged += gridView_SelectionChanged;
}
}
private void gridView_SelectionChanged(object sender, SelectionChangeEventArgs e)
{
DataContext.CallOnClick((DataContext as IHasSelectedItem<IViewModel>)?.SelectedItem);
}
问题的MVVM解决方案是根本不使用IsVisibleChanged
事件。相反,我们只需在视图模型中创建一个bool
属性:
private bool isVisible = false;
public bool IsVisible
{
get { return isVisible; }
set { isVisible = value; NotifyPropertyChanged("IsVisible"); }
}
现在,您可以使用BooleanToVisibilityConverter
:将此属性数据绑定到相关控件的Visibility
属性
Visibility="{Binding IsVisible, Converter={StaticResource BooleanToVisibilityConverter}}"
现在,每当Visibility
属性更改时,就会调用IsVisible
setter,因此您可以在那里处理它:
public bool IsVisible
{
get { return isVisible; }
set
{
isVisible = value;
NotifyPropertyChanged("IsVisible");
// Handle the change of visibility here... maybe call a method from here?
}
}