如何避免使用 MVVM (WPF) 创建视图实例
How to avoid creating instance of View with MVVM (WPF)
我刚刚认识到,每次当我使用 MVVM 并尝试显示一个 ViewModel 及其视图时,都会创建一个视图实例,尽管我只是使用相同的 ViewModel。
在我的视图中是一个 GridView。我在代码隐藏中写了这个来调用ViewModel的事件。
private void gridView_SelectionChanged(object sender, SelectionChangeEventArgs e)
{
DataContext.CallOnClick((DataContext as IHasSelectedItem<IViewModel>)?.SelectedItem);
}
问题在于,如果我在 View 的代码隐藏中定义了一些事件,我将不止一次获得这些事件,因为 View 的实例总是被创建并且每个实例都将事件发送给 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?
}
}
我刚刚认识到,每次当我使用 MVVM 并尝试显示一个 ViewModel 及其视图时,都会创建一个视图实例,尽管我只是使用相同的 ViewModel。
在我的视图中是一个 GridView。我在代码隐藏中写了这个来调用ViewModel的事件。
private void gridView_SelectionChanged(object sender, SelectionChangeEventArgs e)
{
DataContext.CallOnClick((DataContext as IHasSelectedItem<IViewModel>)?.SelectedItem);
}
问题在于,如果我在 View 的代码隐藏中定义了一些事件,我将不止一次获得这些事件,因为 View 的实例总是被创建并且每个实例都将事件发送给 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?
}
}