【发布时间】:2017-01-25 08:07:51
【问题描述】:
我正在分析一个使用 Catel 作为 MVVM 框架的 WPF 应用程序,我已经看到在 ViewModel 中我有 2 个保留路径
现在我在附加到上下文菜单的行为中创建了这样的 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")) }
};
现在命令在
中定义 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);
}
我做错了什么? 谢谢
【问题讨论】:
-
看来 RadMenuItem 订阅了 ICommand.CanExecuteChanged 事件。因此命令绑定到 GUI 并通过事件委托保存菜单项。仍然无法判断您做错了什么,因为您没有描述您期望的行为。
-
当我关闭视图时,我希望 viewmodel 也会被处理掉......但由于这两个引用它仍然存在......但我不明白如何正确处理它们?
-
不,第二种方式不好......您订阅了事件 - 您应该取消订阅它。检查 RadMenuItem 是否实现了 IDisposable 接口,是否在 Dispose 方法中取消订阅 ICommand.CanExecuteChanged。
-
在 .net profiler 中搜索了好几个小时,我也得到了这个。你的问题证实我是正确的。您是否找到任何解决方法?我注意到 RadMenuItem 没有实现 IDisposable
-
根本不可能...
标签: c# wpf mvvm catel dotmemory