我最近将我的应用程序从Catel 3.9.0更新到4.4.0。除了出现在我的大多数视图中的“打印”按钮之外,事情通常都很顺利。
应用程序允许客户选择并加载文本文件,然后对其进行解析和验证。如果有任何错误,它们将显示在网格控件的视图中。显示任何错误还应启用“打印”按钮,让客户预览并打印错误报告。
View架构是:
MyView.xaml (Catel UserControl)
CommonErrorsWarnings.xaml (Catel UserControl)
ErrorsAndWarningsGrid (DevExpress GridControl)
ErrorsAndWarningsGrid绑定到关联ViewModel的公共父类中的ObservableCollection。此ObservableCollection包含包含验证错误/警告的对象。
此外,View是一个打印按钮,绑定到公共父ViewModel类上的命令。它具有以下“可执行”方法:
/// <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方法。它似乎仅在创建ViewModel时首次“设置”集合时调用,而不是在集合被“获取”以向其添加项目时调用。
我已经尝试了Catel documentation中的一些建议:手动添加有趣的属性并注册ViewPropertySelector,但似乎都不起作用。
临时解决方法(来自另一个SO question)是在更新集合后调用ViewModelCommandManager.InvalidateCommands(true),但我关心的是是否有更好/更简单的解决方案。
如果您有任何疑问或需要更多信息,请告诉我们。谢谢!
答案 0 :(得分:0)
出于性能原因,Catel不再自动订阅CommandManager以使状态无效(保存CanExecute调用的 lot )。如果您想要恢复所有这些行为,您可以创建一个自定义类,订阅命令managerand并使命令无效。
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();
}
}
}
}