C# 使用Catel命令更改CanExecuteChange上的内存泄漏

C# 使用Catel命令更改CanExecuteChange上的内存泄漏,c#,wpf,mvvm,catel,dotmemory,C#,Wpf,Mvvm,Catel,Dotmemory,我分析了一个使用Catel作为MVVM框架的WPF应用程序,在一个ViewModel中,我看到了两个保留路径 现在,我在一个附加到上下文菜单的行为中创建这样的RadMenuItem,它们被定义为 protected virtual IEnumerable<RadMenuItem> GetRowMenuItems(RadContextMenu contextMenu) { var rowItems = new List<RadMenuItem>()

我分析了一个使用Catel作为MVVM框架的WPF应用程序,在一个ViewModel中,我看到了两个保留路径

现在,我在一个附加到上下文菜单的行为中创建这样的RadMenuItem,它们被定义为

protected virtual IEnumerable<RadMenuItem> GetRowMenuItems(RadContextMenu contextMenu)
    {
        var rowItems = new List<RadMenuItem>();

        RadMenuItem saveSettings = new RadMenuItem
        {
            Tag = "force",
            Header = CoreResources.LBL_SAVE_SETTINGS,
            Command = DefaultRtViewContextMenuCommands.SaveLayoutDataCommand,
            CommandParameter = AssociatedObject,

            Icon = new Image { Source = new BitmapImage(new Uri("pack://application:,,,/IF.Tesoreria.Client.WPF.Core;component/Media/save.png")) }
        };

        rowItems.Add(saveSettings);

        RadMenuItem loadSettings = new RadMenuItem
        {
            Tag = "force",
            Header = CoreResources.LBL_LOAD_SETTINGS,
            Command = DefaultRtViewContextMenuCommands.LoadLayoutDataCommand,
            CommandParameter = AssociatedObject,
            Icon = new Image { Source = new BitmapImage(new Uri("pack://application:,,,/IF.Tesoreria.Client.WPF.Core;component/Media/load.png")) }
        };
受保护的虚拟IEnumerable GetRowMenuItems(RadContextMenu contextMenu)
{
var rowItems=新列表();
RadMenuItem saveSettings=新RadMenuItem
{
Tag=“force”,
Header=CoreResources.LBL\u保存\u设置,
Command=DefaultRTViewContextMenuCommand.SaveLayoutDataCommand,
CommandParameter=AssociatedObject,
图标=新图像{Source=新位图图像(新Uri(“pack://application:,,,/IF.Tesoreria.Client.WPF.Core;component/Media/save.png”))}
};
添加(保存设置);
RadMenuItem loadSettings=新RadMenuItem
{
Tag=“force”,
Header=CoreResources.LBL\u加载\u设置,
Command=DefaultRTViewContextMenuCommand.LoadLayoutDataCommand,
CommandParameter=AssociatedObject,
图标=新图像{Source=新位图图像(新Uri(“pack://application:,,,/IF.Tesoreria.Client.WPF.Core;component/Media/load.png”))}
};
现在,在中定义了这些命令

    public class DefaultRtViewContextMenuCommands
{
   public static Command<FlexGridCommandParameter> SaveLayoutDataCommand { get; private set; }
    public static Command<FlexGridCommandParameter> LoadLayoutDataCommand { get; private set; }

    private static void OnLoadLayoutCommandExecute(FlexGridCommandParameter grid)
    {
        Argument.IsNotNull(() => grid);

        var dependencyResolver = DependencyResolverManager.Default;
        var openFileService = dependencyResolver.DefaultDependencyResolver.Resolve<IOpenFileService>();
        openFileService.Filter = "Gridview setting file|*.flexgrid";
        if (openFileService.DetermineFile())
        {
            // User selected a file
            using (var fs = File.OpenRead(openFileService.FileName))
            {
                GridViewPersistenceHelper.LoadLayout(grid.Grid, fs, null);
            }
        }
    }

    private static void OnSaveLayoutCommandExecute(FlexGridCommandParameter grid)
    {
        Argument.IsNotNull(() => grid);

        var dependencyResolver = DependencyResolverManager.Default;
        var saveFileService = dependencyResolver.DefaultDependencyResolver.Resolve<ISaveFileService>();
        saveFileService.Filter = "Gridview setting file|*.flexgrid";
        if (saveFileService.DetermineFile())
        {
            // User selected a file
            using (var fs = File.OpenWrite(saveFileService.FileName))
            {
                GridViewPersistenceHelper.SaveLayout(grid.Grid, fs);
            }
        }
    }

 static DefaultRtViewContextMenuCommands()
    {
        viewModelFactory = ServiceLocator.Default.ResolveType<IViewModelFactory>();
        portfolioService = ServiceLocator.Default.ResolveType<IPortfoliosService>();
        pkInstrumentsService = ServiceLocator.Default.ResolveType<IPkInstrumentsService>();

        SaveLayoutDataCommand = new Command<FlexGridCommandParameter>(OnSaveLayoutCommandExecute,_=>true);
        LoadLayoutDataCommand = new Command<FlexGridCommandParameter>(OnLoadLayoutCommandExecute,_=>true);
    }
public类defaultrtviewContextMenuCommand
{
公共静态命令SaveLayoutDataCommand{get;private set;}
公共静态命令LoadLayoutDataCommand{get;private set;}
私有静态void OnLoadLayoutCommandExecute(FlexGridCommandParameter网格)
{
参数.IsNotNull(()=>grid);
var dependencyrolver=dependencyrolvermanager.Default;
var openFileService=dependencysolver.defaultdependencysolver.Resolve();
openFileService.Filter=“Gridview设置文件|*.flexgrid”;
if(openFileService.DetermineFile())
{
//用户选择了一个文件
使用(var fs=File.OpenRead(openFileService.FileName))
{
GridViewPersistenceHelper.LoadLayout(grid.grid,fs,null);
}
}
}
私有静态无效OnSaveLayoutCommandExecute(FlexGridCommandParameter网格)
{
参数.IsNotNull(()=>grid);
var dependencyrolver=dependencyrolvermanager.Default;
var saveFileService=dependencysolver.defaultdependencysolver.Resolve();
saveFileService.Filter=“Gridview设置文件|*.flexgrid”;
if(saveFileService.DetermineFile())
{
//用户选择了一个文件
使用(var fs=File.OpenWrite(saveFileService.FileName))
{
GridViewPersistenceHelper.SaveLayout(grid.grid,fs);
}
}
}
静态默认RTViewContextMenuCommand()
{
viewModelFactory=ServiceLocator.Default.ResolveType();
portfolioService=ServiceLocator.Default.ResolveType();
pkInstrumentsService=ServiceLocator.Default.ResolveType();
SaveLayoutDataCommand=new命令(OnSaveLayoutCommandExecute,=>true);
LoadLayoutDataCommand=new命令(OnLoadLayoutCommandExecute,=>true);
}
我做错了什么? 谢谢


对我来说很有用。你可以反编译并看到,当你这样做时,菜单项会从命令的CanExecuteChanged中注销自己。RadMenuItem似乎订阅了ICommand.CanExecuteChanged事件。因此命令绑定到GUI并通过事件委托保存菜单项。仍然无法判断你做错了什么,因为你没有描述ribe您期望的行为。当我关闭视图时,我期望viewmodel也会被释放…但由于这两个引用,它仍然处于活动状态…但我无法理解如何正确地处理它们?不,第二种方式不好…您订阅了事件-您应该取消订阅。检查RadMenuItem是否实现IDisposable接口,以及它是否NSSubscribes ICommand.CanExecuteChanged in Dispose方法。在.net profiler中搜索了许多小时,我也得到了这个。您的问题证实了我的正确性。您找到了任何解决方法吗?我注意到RadMenuItem根本没有实现IDisposableNo方法。。。
radMenuItem.Command = null;