Catel WPF 延迟验证

Posted

技术标签:

【中文标题】Catel WPF 延迟验证【英文标题】:Catel WPF Deferred Validation 【发布时间】:2013-08-06 23:45:02 【问题描述】:

我刚刚开始将 Catel 用于 WPF 应用程序,但遇到了一些问题。

1) 当按钮无法执行时,根据文档,我没有看到按钮变灰。

2) 我在哪里将代码保存到数据库中 - 在 ViewModel 或 Model 中。有没有例子?

3) 是否有在主页面中使用菜单并在单击菜单项时加载用户控件的示例?

4) 当我在 ViewModel 的构造函数中设置 DeferValidationUntilFirstSaveCall = true 时,对话框窗口出现时出现异常。异常如下

System.NullReferenceException was unhandled by user code
  HResult=-2147467261
  Message=Object reference not set to an instance of an object.
  Source=Catel.MVVM
  StackTrace:
       at Catel.Windows.Data.Converters.GetFirstValidationErrorConverter.Convert(Object value, Type targetType, Object parameter)
       at Catel.Windows.Data.Converters.ValueConverterBase.Convert(Object value, Type targetType, Object parameter, CultureInfo culture)
       at System.Windows.Data.BindingExpression.TransferValue(Object newValue, Boolean isASubPropertyChange)
       at System.Windows.Data.BindingExpression.Activate(Object item)
       at System.Windows.Data.BindingExpression.AttachToContext(AttachAttempt attempt)
       at System.Windows.Data.BindingExpression.AttachOverride(DependencyObject target, DependencyProperty dp)
       at System.Windows.Data.BindingExpressionBase.OnAttach(DependencyObject d, DependencyProperty dp)
       at System.Windows.StyleHelper.GetInstanceValue(UncommonField`1 dataField, DependencyObject container, FrameworkElement feChild, FrameworkContentElement fceChild, Int32 childIndex, DependencyProperty dp, Int32 i, EffectiveValueEntry& entry)
       at System.Windows.StyleHelper.GetChildValueHelper(UncommonField`1 dataField, ItemStructList`1& valueLookupList, DependencyProperty dp, DependencyObject container, FrameworkObject child, Int32 childIndex, Boolean styleLookup, EffectiveValueEntry& entry, ValueLookupType& sourceType, FrameworkElementFactory templateRoot)
       at System.Windows.StyleHelper.GetChildValue(UncommonField`1 dataField, DependencyObject container, Int32 childIndex, FrameworkObject child, DependencyProperty dp, FrugalStructList`1& childRecordFromChildIndex, EffectiveValueEntry& entry, ValueLookupType& sourceType, FrameworkElementFactory templateRoot)
       at System.Windows.StyleHelper.GetValueFromStyleOrTemplate(FrameworkObject fo, DependencyProperty dp, EffectiveValueEntry& entry)
       at System.Windows.StyleHelper.ApplyStyleOrTemplateValue(FrameworkObject fo, DependencyProperty dp)
       at System.Windows.StyleHelper.InvalidateContainerDependents(DependencyObject container, FrugalStructList`1& exclusionContainerDependents, FrugalStructList`1& oldContainerDependents, FrugalStructList`1& newContainerDependents)
       at System.Windows.StyleHelper.DoStyleInvalidations(FrameworkElement fe, FrameworkContentElement fce, Style oldStyle, Style newStyle)
       at System.Windows.StyleHelper.UpdateStyleCache(FrameworkElement fe, FrameworkContentElement fce, Style oldStyle, Style newStyle, Style& styleCache)
       at System.Windows.FrameworkElement.OnStyleChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
       at System.Windows.DependencyObject.OnPropertyChanged(DependencyPropertyChangedEventArgs e)
       at System.Windows.FrameworkElement.OnPropertyChanged(DependencyPropertyChangedEventArgs e)
       at System.Windows.Controls.TextBox.OnPropertyChanged(DependencyPropertyChangedEventArgs e)
       at System.Windows.DependencyObject.NotifyPropertyChange(DependencyPropertyChangedEventArgs args)
       at System.Windows.DependencyObject.UpdateEffectiveValue(EntryIndex entryIndex, DependencyProperty dp, PropertyMetadata metadata, EffectiveValueEntry oldEntry, EffectiveValueEntry& newEntry, Boolean coerceWithDeferredReference, Boolean coerceWithCurrentValue, OperationType operationType)
       at System.Windows.DependencyObject.InvalidateProperty(DependencyProperty dp, Boolean preserveCurrentValue)
       at System.Windows.FrameworkElement.UpdateStyleProperty()
       at System.Windows.FrameworkElement.OnInitialized(EventArgs e)
       at System.Windows.FrameworkElement.TryFireInitialized()
       at System.Windows.FrameworkElement.EndInit()
       at MS.Internal.Xaml.Runtime.ClrObjectRuntime.InitializationGuard(XamlType xamlType, Object obj, Boolean begin)
       at MS.Internal.Xaml.Runtime.PartialTrustTolerantRuntime.InitializationGuard(XamlType xamlType, Object obj, Boolean begin)
       at System.Xaml.XamlObjectWriter.Logic_EndInit(ObjectWriterContext ctx)
       at System.Xaml.XamlObjectWriter.WriteEndObject()
       at System.Xaml.XamlWriter.WriteNode(XamlReader reader)
       at System.Windows.Markup.WpfXamlLoader.TransformNodes(XamlReader xamlReader, XamlObjectWriter xamlWriter, Boolean onlyLoadOneNode, Boolean skipJournaledProperties, Boolean shouldPassLineNumberInfo, IXamlLineInfo xamlLineInfo, IXamlLineInfoConsumer xamlLineInfoConsumer, XamlContextStack`1 stack, IStyleConnector styleConnector)
       at System.Windows.Markup.WpfXamlLoader.Load(XamlReader xamlReader, IXamlObjectWriterFactory writerFactory, Boolean skipJournaledProperties, Object rootObject, XamlObjectWriterSettings settings, Uri baseUri)
       at System.Windows.Markup.WpfXamlLoader.LoadBaml(XamlReader xamlReader, Boolean skipJournaledProperties, Object rootObject, XamlAccessLevel accessLevel, Uri baseUri)
       at System.Windows.Markup.XamlReader.LoadBaml(Stream stream, ParserContext parserContext, Object parent, Boolean closeStream)
       at System.Windows.Application.LoadComponent(Object component, Uri resourceLocator)
       at FNZCIressClient.Views.AccountMappingWindow.InitializeComponent() in h:\Documents\iress-utils\FNZCIressClient\FNZCIressClient\Views\AccountMappingWindow.xaml:line 1
       at FNZCIressClient.Views.AccountMappingWindow..ctor(AccountMappingViewModel viewModel) in h:\Documents\iress-utils\FNZCIressClient\FNZCIressClient\Views\AccountMappingWindow.xaml.cs:line 28
  InnerException: 

如果我从代码中删除延迟验证行,弹出窗口会起作用。

感谢任何帮助和建议。

【问题讨论】:

【参考方案1】:

1) 看看examples repository,有很多例子。

2) 重写 Save() 方法

3) 使用 UIVisualizerService 或 Prism 动态加载区域

4) 我会调查的。您只是使用 DataWindow 还是自定义的?

【讨论】:

1) 当我从示例中运行 Catel.WPF.PersonApplication 时,也没有任何按钮变灰。我错过了什么吗? 2)在视图模型中?我没有看到模型中的任何方法被调用 3)我根据 MyMediaStuff 演示使用了一个控制模板 4)只是一个普通的 DataWindow 我也在尝试将 Catel 与 BrightstarDB 一起使用。 BrightStarDB 为每个实体生成一个部分类,该类对接口/类中的每个字段都有自己的属性。这些与通过 modelprop sn-ps 用于 Catel 的属性发生冲突。您有什么想法可以将 BrighstarDB 与 Catel 结合起来吗? 请尝试更新的演示。 “MyMediaStuff”真的很老了,所有最新的示例都在示例存储库中保持最新。当没有选择任何内容时,PersonApplication 会灰显(当没有选择任何人时,应该禁用编辑按钮)。只要 BrighstarDB 实现 INotifyPropertyChanged(最好是 IEditableObject),它就可以正常工作。 我刚刚下载了最新的 Catel.Examples 存储库。我将调试配置修改为仅构建 Catel.Examples.WPF.Models 和 Catel.Examples.WPF.PersonApplication。它构建没有错误。运行时,没有任何选择,“编辑”和“删除”按钮不会变灰。 见dl.dropboxusercontent.com/u/8455721/***/…,他们被禁用了。也许它们没有变灰,但仍然被禁用。

以上是关于Catel WPF 延迟验证的主要内容,如果未能解决你的问题,请参考以下文章

Catel 延迟加载包含视图/视图模型的程序集

viewmodel + Catel 上的验证

Catel 中的嵌套验证

使用 Catel 创建多个 WPF 应用程序

使用 WPF 在 Catel 中设置 DataContext

Catel MVVM 结构