我刚刚使用 MVVM 模式完成了用 WPF 和 c# 编写的桌面应用程序。在这个应用程序中,我使用了 Delegate Command 实现来包装在我的 ModelView 中公开的 ICommands 属性。问题是这些 DelegateCommands 阻止我的 ModelView 和 View 在关闭视图后被垃圾收集。所以它一直在闲逛,直到我终止整个应用程序。我对应用程序进行了概要分析,我发现这完全是关于将模型视图保存在内存中的委托命令。我怎样才能避免这种情况,这是 mvvm 模式的本质,还是与我植入该模式有关?谢谢。
编辑:这是我如何实现 MVVM 模式的一小部分但完整的部分
第一个:CommandDelegte 类
class DelegateCommand:ICommand
{
private Action<object> execute;
private Predicate<object> canExcute;
public DelegateCommand(Action<object> execute, Predicate<object> canExecute)
{
if (execute == null)
{
throw new ArgumentNullException("execute");
}
this.execute = execute;
this.canExcute = canExecute;
}
public bool CanExecute(object parameter)
{
if (this.canExcute != null)
{
return canExcute(parameter);
}
return true;
}
public event EventHandler CanExecuteChanged
{
add { CommandManager.RequerySuggested += value; }
remove { CommandManager.RequerySuggested -= value; }
}
public void Execute(object parameter)
{
this.execute(parameter);
}
}
二:ModelView类
public class ViewModel:DependencyObject, INotifyPropertyChanged
{
private DelegateCommand printCommand;
public ICommand PrintCommand
{
get
{
if (printCommand == null)
{
printCommand = new DelegateCommand(Print, CanExecutePrint);
}
return printCommand;
}
}
void Print(object obj)
{
Console.WriteLine("Print Command");
}
bool CanExecutePrint(object obj)
{
return true;
}
public event PropertyChangedEventHandler PropertyChanged;
private void OnProeprtyChanged(string propertyName)
{
if (PropertyChanged != null)
{
PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
}
}
三:后面的窗口代码
public MainWindow()
{
InitializeComponent();
base.DataContext = new ViewModel();
}
第四:我的 XAML
<Window x:Class="WpfApplication1.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow" Height="350" Width="525">
<Window.InputBindings>
<KeyBinding Key="P" Modifiers="Control" Command="{Binding Path=PrintCommand}"/>
</Window.InputBindings>
<StackPanel>
<Button Content="Print - Ctrl+P" Width="75" Height="75" Command="{Binding Path=PrintCommand}"/>
</StackPanel>