まずは、データーフローから考えてみると
値の変更→データチェック→通知
OK => INotifyPropertyChange
NG => INotifyDataErrorInfo
という流れで実装する場合、
set {
if (validation(value)) {
//INotifyPropertyChange
}else{
//INotifyDataErrInfo
}
}
この辺りは共通処理になるからここをModelBaseクラスという形で実装しておき、
あとはSetProperty関数を用いて上記処理を処理させようというアプローチである。
過去にもModelがらみの記事に書いた
MongoDBと接続、もしくはJSonファイルに出力する方法にも使えるようにしておいた。
実装方法はModelBaseクラス内でNotify関連を実装してそれを任意のModelクラスに継承するやり方。
Imports System.ComponentModel Imports MongoDB.Driver Imports MongoDB.Driver.Builders Imports MongoDB.Driver.Linq Imports MongoDB.Bson Imports MongoDB.Bson.Serialization.Attributes 'http://blog.micic.ch/net/easy-mvvm-example-with-inotifypropertychanged-and-inotifydataerrorinfo Public Class ModelBase : Implements INotifyPropertyChanged, INotifyDataErrorInfo #Region "data error" Private _errors As New Dictionary(Of String, List(Of String)) Public Event ErrorsChanged(sender As Object, e As DataErrorsChangedEventArgs) Implements INotifyDataErrorInfo.ErrorsChanged Public Function GetErrors(propertyName As String) As IEnumerable Implements INotifyDataErrorInfo.GetErrors If _errors.ContainsKey(propertyName) Then Return _errors(propertyName) End If Return Nothing End Function Public ReadOnly Property HasErrors As Boolean Implements INotifyDataErrorInfo.HasErrors Get Return 0 < _errors.Count End Get End Property Public ReadOnly Property IsValid As Boolean Get Return Not HasErrors End Get End Property Private Sub AddError(propertyName As String, errmsg As String) If Not _errors.ContainsKey(propertyName) Then _errors(propertyName) = New List(Of String) End If If Not _errors(propertyName).Contains(errmsg) Then _errors(propertyName).Add(errmsg) RaiseEvent ErrorsChanged(Me, New DataErrorsChangedEventArgs(propertyName)) End If End Sub Private Sub RemoveError(propertyName As String) If _errors.ContainsKey(propertyName) Then _errors.Remove(propertyName) RaiseEvent ErrorsChanged(Me, New DataErrorsChangedEventArgs(propertyName)) End If End Sub #End Region #Region "Property changed" Public Event PropertyChanged(sender As Object, e As PropertyChangedEventArgs) Implements INotifyPropertyChanged.PropertyChanged #End Region #Region "Set Property" Private _lock As New Object() Protected Delegate Function DlgCheckValidation() As String Protected Sub SetProperty(Of T)(propertyName As String, ByRef field As T, value As T, func As DlgCheckValidation) If Not EqualityComparer(Of T).Default.Equals(field, value) Then SyncLock _lock Dim errmsg = "" If Not IsNothing(func) Then errmsg = func() End If If "" = errmsg Then field = value RemoveError(propertyName) RaiseEvent PropertyChanged(Me, New PropertyChangedEventArgs(propertyName)) Else AddError(propertyName, errmsg) End If End SyncLock End If End Sub #End Region End Class <BsonIgnoreExtraElements> Public Class AddressModel : Inherits ModelBase <BsonId> <DisplayName("ID")> Public Property _id As BsonObjectId Private _name As String Private _birthday As Date Private _emailAddress As List(Of EMailModel) <DisplayName("名前")> Public Property name As String Get Return _name End Get Set(value As String) SetProperty("name", _name, value, Function() As String If "abc" = value Then Return "abc not allowed" End If Return "" End Function) End Set End Property Public Property Birthday As Date Get Return _birthday End Get Set(value As Date) SetProperty("Birthday", _birthday, value, Nothing) End Set End Property Public Property EMailAddress As List(Of EMailModel) Get Return _emailAddress End Get Set(value As List(Of EMailModel)) SetProperty("EMailAddress", _emailAddress, value, Nothing) End Set End Property End Class <BsonIgnoreExtraElements> Public Class EMailModel : Inherits ModelBase Private _DisplayName As String Private _MailAddress As String Public Property DisplayName As String Get Return _DisplayName End Get Set(value As String) SetProperty("DisplayName", _DisplayName, value, Nothing) End Set End Property Public Property MailAddress As String Get Return _MailAddress End Get Set(value As String) SetProperty("MailAddress", _MailAddress, value, Nothing) End Set End Property End Class
参照サイト:
http://ivis-mynikki.blogspot.jp/2013/01/net-or.htmlhttp://ivis-mynikki.blogspot.jp/2014/03/blog-post.html
http://blog.micic.ch/net/easy-mvvm-example-with-inotifypropertychanged-and-inotifydataerrorinfo