2011-08-29 47 views
1

我正在开发一个WPF应用程序(使用MVVM)并在我的ViewModel上实现了IDataErrorInfo。我的部分验证检查是必填字段已输入。这适用于编辑现有记录,但在添加新记录时不提供良好的用户体验。只要我加载新的视图,强制性的字段突出显示为无效。如何阻止IDataErrorInfo发射新物品?

有没有一个(最好是非hacky)解决方案?这似乎是一个非常标准的事情,所以我希望我缺少一些简单的东西。

+0

在我看来,这是正确的行为。只要未输入必填字段,对象就无效。 –

+0

是的,我同意它最终运作正常。然而,这并不是用户期望的。作为一个用户,我甚至在做任何事情之前都会被告知我做了什么是错误的。 – s1mm0t

+0

@ s1mm0t:对我来说,你是一个实现IDataErrorInfo的人。您可以确定您的实例是否仍处于初始化状态并从此处启动。 – Will

回答

3

使用一个标志来指示记录是否是新的。在IDataErrorInfo的实现中检查此标志,并在用户第一次尝试验证输入时将该标志设置为true。

+0

这似乎是我希望避免的那种哈克解决方案,但要感谢它可能是唯一的解决方案。 – s1mm0t

+0

尽管我不想使用国旗,但因为我正在进行验证,所以我最终被迫退出。尽管它隐藏在基础类中,所以我想我可以忍受它:O) – s1mm0t

1

我通常在我的实体或数据类上有一个子类,它在初始化后从我的错误词典中删除所有条目。我在实例化后调用它。

您可以更进一步,并为New对象设置为False的初始化字段(布尔值),对于现有对象设置True。

您不希望用户出现一堆错误/验证模板,仅仅是因为它们已经生成了一个新对象并且尚未用数据填充它。

视图模型实例

在这个例子中,我从我的ViewModel属性。当Shipment对象被加载时,该属性将调用错误字典上的Clear方法。如果货件是来自数据库的持久记录,则它应具有有效数据,因为必须对其进行验证才能保存到数据库。如果是新的,则条目将被删除,用户将看到一个新的表单准备好输入。

Public Property ShipmentRecord() As Shipment 
    Get 
     Return _shpShipmentRecord 
    End Get 
    Set(ByVal value As Shipment) 
     _shpShipmentRecord = value 
     ShipmentRecord.m_dirtyFields.Clear() 
     OnPropertyChanged("ShipmentRecord") 
    End Set 
End Property 

不幸的是,这是我能找到的第一个例子,它直接访问m_dirtyFields词典(这本来是私人的,但我将它设置为好友。)在大多数情况下我会创建访问字典的方法代替。

+0

这听起来像比使用标志更好的解决方案。但是,你可以确保这个初始化代码在调用Item属性之后运行*吗? – s1mm0t

+0

我过去所做的是在将对象分配给ViewModel时清除字典。例如见上文。 – CodeWarrior

3

而不是使用 “ValidatesOnDataErrors =真”,你可以手动添加DataErrorValidationRule,与ValidatesOnTargetUpdated属性:

<TextBox> 
    <TextBox.Text> 
    <Binding Path="..." ValidatesOnExceptions="true"> 
     <Binding.ValidationRules> 
      <DataErrorValidationRule ValidatesOnTargetUpdated="false"/> 
     </Binding.ValidationRules> 
    </Binding> 
    </TextBox.Text> 
</TextBox>