更新到 Catel 4.4.0 后未触发命令的 CanExecute 方法
CanExecute method of command not firing after update to Catel 4.4.0
我最近将我的应用程序从 Catel 3.9.0 更新到 4.4.0。除了出现在我大多数视图中的打印按钮外,一切正常。
该应用程序允许客户 select 并加载一个文本文件,然后对其进行解析和验证。如果有任何错误,它们将显示在网格控件的视图中。显示任何错误还应启用“打印”按钮,让客户预览和打印错误报告。
视图架构是:
MyView.xaml (Catel UserControl)
CommonErrorsWarnings.xaml (Catel UserControl)
ErrorsAndWarningsGrid (DevExpress GridControl)
ErrorsAndWarningsGrid 绑定到关联 ViewModel 的公共父 class 中的 ObservableCollection。此 ObservableCollection 包含包含验证 errors/warnings.
的对象
View 上还有一个打印按钮,绑定到公共父 ViewModel class 上的命令。它具有以下 "can execute" 方法:
/// <summary>
/// Method to check whether the PrintReport command can be executed.
/// </summary>
/// <returns><c>true</c> if the command can be executed; otherwise <c>false</c></returns>
protected virtual bool OnPrintReportCanExecute()
{
Debug.Print(string.Format("OnPrintReportCanExecute called in [{0}]. Errors/Warnings count = {1}", this.Title, this.RecordErrorsAndWarnings.Count));
return this.RecordErrorsAndWarnings != null && this.RecordErrorsAndWarnings.Count > 0;
}
(Debug.Print 语句只是为了帮助了解何时调用此方法。)
所有这一切在 Catel 3.9.0 中运行良好——当客户加载文本文件并将验证错误添加到 RecordErrorsAndWarnings 集合时,打印按钮被启用。移动到 4.4.0 后,它已停止工作。 OnPrintReportCanExecute 方法不像在 3.9.0 中那样经常被调用,而且在 RecordErrorsAndWarnings 计数大于 0 时也不会被调用。看起来 CanExecute 方法没有被调用 during/after 集合已更新。它似乎只在创建 ViewModel 时集合是第一个 "set" 时被调用,但当集合是 "gotten" 时不会调用它来向它添加项目。
我尝试了 Catel documentation 中的一些建议:手动添加有趣的属性并注册 ViewPropertySelector,但似乎都不起作用。
临时解决方法(来自另一个 SO question)是在更新集合后调用 ViewModelCommandManager.InvalidateCommands(true),但我担心是否有 better/simpler 解决方案。
如果您有任何疑问或需要更多信息,请告诉我。谢谢!
出于性能原因,Catel 不再自动订阅 CommandManager 以使状态无效(节省 lot 的 CanExecute 调用)。如果您想要恢复所有这些行为,您可以创建一个自定义 class 订阅命令管理器并为您使命令无效。
2 条免责声明
- 这是出于某种原因(性能)而被删除的,因此这不是推荐的方法。但这可以让你找回旧的行为。
- 我还没有测试过这段代码,但它应该几乎开箱即用。
代码
public class RequeryAllTheThings
{
private IViewModelManager _viewModelManager;
public RequeryAllTheThings(IViewModelManager viewModelManager)
{
Argument.IsNotNull(() => viewModelManager);
_viewModelManager = viewModelManager;
System.Windows.Input.CommandManager.RequerySuggested += OnCommandManagerRequerySuggested;
}
private void OnCommandManagerRequerySuggested(object sender, SomeEventArgs e)
{
InvalidateCommands();
}
private void InvalidateCommands()
{
var viewModels = _viewModelManager.ActiveViewModels;
foreach (var viewModel in viewModels)
{
var viewModelBase = viewModel as ViewModelBase;
if (viewModelBase != null)
{
var viewModelCommandManager = viewModelBase.GetViewModelCommandManager();
viewModelCommandManager.InvalidateCommands();
}
}
}
}
我最近将我的应用程序从 Catel 3.9.0 更新到 4.4.0。除了出现在我大多数视图中的打印按钮外,一切正常。
该应用程序允许客户 select 并加载一个文本文件,然后对其进行解析和验证。如果有任何错误,它们将显示在网格控件的视图中。显示任何错误还应启用“打印”按钮,让客户预览和打印错误报告。
视图架构是:
MyView.xaml (Catel UserControl)
CommonErrorsWarnings.xaml (Catel UserControl)
ErrorsAndWarningsGrid (DevExpress GridControl)
ErrorsAndWarningsGrid 绑定到关联 ViewModel 的公共父 class 中的 ObservableCollection。此 ObservableCollection 包含包含验证 errors/warnings.
的对象View 上还有一个打印按钮,绑定到公共父 ViewModel class 上的命令。它具有以下 "can execute" 方法:
/// <summary>
/// Method to check whether the PrintReport command can be executed.
/// </summary>
/// <returns><c>true</c> if the command can be executed; otherwise <c>false</c></returns>
protected virtual bool OnPrintReportCanExecute()
{
Debug.Print(string.Format("OnPrintReportCanExecute called in [{0}]. Errors/Warnings count = {1}", this.Title, this.RecordErrorsAndWarnings.Count));
return this.RecordErrorsAndWarnings != null && this.RecordErrorsAndWarnings.Count > 0;
}
(Debug.Print 语句只是为了帮助了解何时调用此方法。)
所有这一切在 Catel 3.9.0 中运行良好——当客户加载文本文件并将验证错误添加到 RecordErrorsAndWarnings 集合时,打印按钮被启用。移动到 4.4.0 后,它已停止工作。 OnPrintReportCanExecute 方法不像在 3.9.0 中那样经常被调用,而且在 RecordErrorsAndWarnings 计数大于 0 时也不会被调用。看起来 CanExecute 方法没有被调用 during/after 集合已更新。它似乎只在创建 ViewModel 时集合是第一个 "set" 时被调用,但当集合是 "gotten" 时不会调用它来向它添加项目。
我尝试了 Catel documentation 中的一些建议:手动添加有趣的属性并注册 ViewPropertySelector,但似乎都不起作用。
临时解决方法(来自另一个 SO question)是在更新集合后调用 ViewModelCommandManager.InvalidateCommands(true),但我担心是否有 better/simpler 解决方案。
如果您有任何疑问或需要更多信息,请告诉我。谢谢!
出于性能原因,Catel 不再自动订阅 CommandManager 以使状态无效(节省 lot 的 CanExecute 调用)。如果您想要恢复所有这些行为,您可以创建一个自定义 class 订阅命令管理器并为您使命令无效。
2 条免责声明
- 这是出于某种原因(性能)而被删除的,因此这不是推荐的方法。但这可以让你找回旧的行为。
- 我还没有测试过这段代码,但它应该几乎开箱即用。
代码
public class RequeryAllTheThings
{
private IViewModelManager _viewModelManager;
public RequeryAllTheThings(IViewModelManager viewModelManager)
{
Argument.IsNotNull(() => viewModelManager);
_viewModelManager = viewModelManager;
System.Windows.Input.CommandManager.RequerySuggested += OnCommandManagerRequerySuggested;
}
private void OnCommandManagerRequerySuggested(object sender, SomeEventArgs e)
{
InvalidateCommands();
}
private void InvalidateCommands()
{
var viewModels = _viewModelManager.ActiveViewModels;
foreach (var viewModel in viewModels)
{
var viewModelBase = viewModel as ViewModelBase;
if (viewModelBase != null)
{
var viewModelCommandManager = viewModelBase.GetViewModelCommandManager();
viewModelCommandManager.InvalidateCommands();
}
}
}
}