prism复合式命令解绑内存泄漏

prism使用复合式命令时,因为自实现的composite command 相当于第三方,存放了vm里command的引用,如果不能使用UnregisterCommand方法回收命令可能会导致内存泄漏。请考虑以下几种情况

1.当所有内容都在同一视图模型

正如官方文档说的那样,某一个view有多个部分(保存逻辑相互独立成单独的command),有个保存按钮可以同时保存所有的内容。这个时候手动UnregisterCommand不会有任何问题,因为都在同一个vm中。

2.打开一个对话框,对话框有几个视图可以相互导航且是单独的viewmodel,各自有着自己保存逻辑。对话框vm有一个全局命令保存所有内容。

因为我们的vm依赖注入常常是瞬态的,如果我打开对话框再去关闭,再打开,你会发现command被注册了多次。这时候需要显示在我们接口增加回收的方法,在对话框关闭时显示解绑绑定。

一个简单的注册视图模型,绑定了登录命令

public UserRegisterViewModel(IRegionManager regionManager, ISettingsCommand settingsCommand,IEventAggregator aggregator)
    {
        _regionManager = regionManager;
        _aggregator = aggregator;

        LoginCommand = new DelegateCommand(Login);
        GoBackCommand = new DelegateCommand(() =>
        {
            if (_navigationJournal.CanGoBack)
            {
                _navigationJournal.GoBack();
            }
        });
        settingsCommand.SaveCommand.RegisterCommand(LoginCommand);
    }

登录视图模型绑定了注册命令

public UserLoginViewModel(IRegionManager regionManager,ISettingsCommand settingsCommand)
    {
        _regionManager = regionManager;
        _settingsCommand = settingsCommand;
        RegisterCommand = new DelegateCommand(Register).ObservesCanExecute(()=>IsEnabled);
        settingsCommand.SaveCommand.RegisterCommand(RegisterCommand);
    }

CompositeCommand

public interface ISettingsCommand
{
    CompositeCommand SaveCommand { get; }

    void UnRegisterSaveCommand();

    void UnRegisterAllCommand();
}
public class SettingsCommand:ISettingsCommand
{
    public CompositeCommand SaveCommand { get; } = new CompositeCommand(true);

    public void UnRegisterSaveCommand()
    {
        SaveCommand.RegisteredCommands.ToList().ForEach(x=> SaveCommand.UnregisterCommand(x));
    }

    public void UnRegisterAllCommand()
    {
        UnRegisterSaveCommand();
    }
}

在对话框视图模型关闭时解绑绑定

public class SettingDialogViewModel : BindableBase, IAppDialogAware
{
    private readonly IRegionManager _regionManager;
    private ISettingsCommand _settingsCommand;
    
    public event Action<IDialogResult> RequestClose;

    public ISettingsCommand SettingsCommand
    {
        get => _settingsCommand;
        set => SetProperty(ref _settingsCommand,value);
    }

	public SettingDialogViewModel(IRegionManager regionManager, ISettingsCommand settingsCommand)
    {
        _regionManager = regionManager;
        SettingsCommand = settingsCommand;
    }

    public bool CanCloseDialog()
    {
        return true;
    }

    public void OnDialogClosed()
    {
        _settingsCommand.UnRegisterSaveCommand();

        DialogParameters parameters = new DialogParameters { { "LoginResult", true } };
        RequestClose?.Invoke(new DialogResult(ButtonResult.OK, parameters));
    }
    
    public void OnDialogOpened(IDialogParameters parameters)
    {
    }
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值