我最终最终使用了以下内容。我将模型更改为使用 LINQ 来自我跟踪实体(有关 STE http://msdn.microsoft.com/en-us/library/vstudio/ff407090%28v=vs.100%29.aspx的信息,请参阅这篇文章)。
LINQ to STE 创建一个实现 iNotifyPropertyChanged 接口的 OnPropertyChanged 事件。
我刚刚为我想要的匹配模型对象(linq 实体生成的代码)创建了一个公共部分类,并为该事件添加了一个事件处理程序OnPropertyChanged
。然后,我使用该IDataErrorInfo
接口来验证并根据需要抛出错误。这使我可以在字段更改时验证它们并反映给用户。这也允许您执行更高级的验证逻辑,可能需要重新查询数据库(即查找用户名是否已被使用等)或抛出一个对话框
此外,如果我执行绕过 UI 的直接“批处理”操作,在模型中进行数据验证允许我仍然进行验证。
然后我使用HasErrors
andHasChanges
属性并使用它们创建一个附加到中继命令的布尔值,如果出现错误,则禁用 crud 命令按钮。
我将发布一些简单的代码来概述我刚刚描述的内容,如果您需要更多详细信息,请发表评论。
这是模型类的实体框架扩展:
Imports System.ComponentModel
Partial Public Class client
Implements IDataErrorInfo
#Region "Properties / Declarations"
'Collection / error description
Private m_validationErrors As New Dictionary(Of String, String)
Private _HasChanges As Boolean = False
''Marks object as dirty, requires saving
Public Property HasChanges() As Boolean
Get
Return _HasChanges
End Get
Set(value As Boolean)
If Not Equals(_HasChanges, value) Then
_HasChanges = value
OnPropertyChanged("HasChanges")
End If
End Set
End Property
'Extends the class with a property that determines
'if the instance has validation errors
Public ReadOnly Property HasErrors() As Boolean
Get
Return m_validationErrors.Count > 0
End Get
End Property
#End Region
#Region "Base Error Objects"
'Returns an error message
'In this case it is a general message, which is
'returned if the list contains elements of errors
Public ReadOnly Property [Error] As String Implements System.ComponentModel.IDataErrorInfo.Error
Get
If m_validationErrors.Count > 0 Then
Return "Client data is invalid"
Else
Return Nothing
End If
End Get
End Property
Default Public ReadOnly Property Item(ByVal columnName As String) As String Implements System.ComponentModel.IDataErrorInfo.Item
Get
If m_validationErrors.ContainsKey(columnName) Then
Return m_validationErrors(columnName).ToString
Else
Return Nothing
End If
End Get
End Property
#End Region
#Region "Base Error Methods"
'Adds an error to the collection, if not already present
'with the same key
Private Sub AddError(ByVal columnName As String, ByVal msg As String)
If Not m_validationErrors.ContainsKey(columnName) Then
m_validationErrors.Add(columnName, msg)
End If
End Sub
'Removes an error from the collection, if present
Private Sub RemoveError(ByVal columnName As String)
If m_validationErrors.ContainsKey(columnName) Then
m_validationErrors.Remove(columnName)
End If
End Sub
#End Region
Public Sub New()
Me.HasChanges = False
End Sub
#Region "Data Validation Methods"
''handles event and calls function that does the actual validation so that it can be called explicitly for batch processes
Private Sub ValidateProperty(ByVal sender As Object, ByVal e As PropertyChangedEventArgs) Handles Me.PropertyChanged
If e.PropertyName = "HasChanges" Then
Exit Sub
End If
IsPropertyValid(e.PropertyName)
HasChanges = True
End Sub
Public Function IsPropertyValid(sProperty As String) As Boolean
Select Case sProperty
''add validation by column name here
Case "chrLast"
If Me.chrLast.Length < 4 Then
Me.AddError("chrLast", "The last name is too short")
Return True
Else
Me.RemoveError("chrLast")
Return False
End If
Case Else
Return False
End Select
End Function
#End Region
End Class
然后在视图模型中我包含以下代码来绑定命令并评估它是否可以执行。
Public ReadOnly Property SaveCommand() As RelayCommand
Get
If _SaveCommand Is Nothing Then
_SaveCommand = New RelayCommand(AddressOf SaveExecute, AddressOf CanSaveExecute)
End If
Return _SaveCommand
End Get
End Property
Private Function CanSaveExecute() As Boolean
Try
If Selection.HasErrors = False And Selection.HasChanges = True Then
Return True
Else
Return False
End If
Catch ex As Exception
Return False
End Try
End Function
Private Sub SaveExecute()
''this is my LINQ to Self Tracking Entities DataContext
FTC_Context.SaveChanges()
End Sub
以下是我绑定按钮的方式(在 WPF 中有自定义样式)
<Button Content="" Height="40" Style="{DynamicResource ButtonAdd}" Command="{Binding SaveCommand}" Width="40" Cursor="Hand" ToolTip="Save Changes" Margin="0,0,10,10"/>
因此,当没有验证错误并且当前客户端记录“isDirty”时,保存按钮会自动启用,如果这两个条件中的任何一个失败,则会禁用。这样,我现在有一种简单的方法来验证我想要的实体的任何类型的列/数据,并且我可以在用户在表单中输入数据时提供反馈,并且只有在我的所有“条件”都被启用后才启用 CRUD 命令按钮遇见了。
这是一场需要弄清楚的战斗。