3

wpf mvvm-lightデータ検証を検索すると、グーグルが返すすべての記事を読んだと思いますが、どちらに進むべきかわかりません。私は、josh smith、Karl Shifflett、およびMVVMLIGHT独自のデータ検証のデモ手法を知っています。私が見ているのは、ほとんどの検証では、ビューモデルでモデルを完全に「再抽象化」する必要があるということです。つまり、検証するモデルのプロパティごとに、ビューモデルにプロパティを作成する必要があります(場合によっては、これらすべてをバインディング/検証用の文字列値に変換します)。ほとんどのフィールドを必須としてマークするだけの場合、これは多くの冗長性のように思えます。

SQLサーバーDBからのモデルクラスのエンティティフレームワーク(セルフトラッキング付き)にLINQを使用しています。結果として、ビジネスデータの検証/ルールをビューモデル内に保持したいと思います。モデルからデータを取得してビューモデルに渡すためのシンプルなサービスインターフェイスを作成します。

私が見つけることができる例のほとんどは、2008年までさかのぼります(つまり、josh smith)。これらの手法はまだ有効ですか、それとも.NET4.5などを使用したmvvmデータ検証の最新のベストプラクティスがありますか。

だから私は尋ねています:

1)どの方法を使用することをお勧めしますか2)MVVM-Light環境を使用したLINQtoEFで最も効果的な方法はどれですか。3)編集:ユーザーがフォームを送信するときだけでなく、データを入力するときにフィードバックを提供したい

ありがとう

4

2 に答える 2

0

これを行う方法(必ずしも正しいとは限りません)は、ViewModel(CRUD操作が通常行われる場所)で検証を行い、検証エラーが発生した場合は、データの保存/追加を中止Messenger.Default.Sendし、にカスタムメッセージタイプを送信するために使用します私の見解。次に、DialogBoxなどを介してユーザーに警告します。

私は過去にBindingValidationRulesを試しましたが、最も信頼性が高く一貫性のある方法は単純なifステートメントであることがわかりました。

于 2013-01-19T07:28:01.523 に答える
0

最終的には以下を使用することになりました。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をバイパスする直接の「バッチ」操作を実行した場合でも検証を行うことができます。

次に、HasErrorsandHasChangesプロパティを使用し、それらを使用して、リレーコマンドに付加されるブール値を作成し、エラーが存在する場合はcrudコマンドボタンを無効にしました。

今説明した内容の概要を説明する簡単なコードを投稿します。詳細が必要な場合はコメントしてください。

モデルクラスのEntityFramework拡張機能は次のとおりです。

 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」の場合、保存ボタンは自動的に有効になり、これら2つの条件のいずれかが失敗した場合は無効になります。このようにして、エンティティに必要な任意のタイプの列/データを検証する簡単な方法があり、フォームにデータを入力するときにユーザーフィードバックを提供し、すべての「条件」が完了した後でのみCRUDコマンドボタンを有効にすることができます。会った。

これは理解するのにかなりの戦いでした。

于 2013-01-21T09:07:25.013 に答える