@@ -153,6 +153,60 @@ public void Test_ObservableValidator_ValidateReturn(string value, bool isValid)
153153 }
154154 }
155155
156+ [ TestCategory ( "Mvvm" ) ]
157+ [ TestMethod ]
158+ public void Test_ObservableValidator_TrySetProperty ( )
159+ {
160+ var model = new Person ( ) ;
161+ var events = new List < DataErrorsChangedEventArgs > ( ) ;
162+
163+ model . ErrorsChanged += ( s , e ) => events . Add ( e ) ;
164+
165+ // Set a correct value, this should update the property
166+ Assert . IsTrue ( model . TrySetName ( "Hello" , out var errors ) ) ;
167+ Assert . IsTrue ( errors . Count == 0 ) ;
168+ Assert . IsTrue ( events . Count == 0 ) ;
169+ Assert . AreEqual ( model . Name , "Hello" ) ;
170+ Assert . IsFalse ( model . HasErrors ) ;
171+
172+ // Invalid value #1, this should be ignored
173+ Assert . IsFalse ( model . TrySetName ( null , out errors ) ) ;
174+ Assert . IsTrue ( errors . Count > 0 ) ;
175+ Assert . IsTrue ( events . Count == 0 ) ;
176+ Assert . AreEqual ( model . Name , "Hello" ) ;
177+ Assert . IsFalse ( model . HasErrors ) ;
178+
179+ // Invalid value #2, same as above
180+ Assert . IsFalse ( model . TrySetName ( "This string is too long for the target property in this model and should fail" , out errors ) ) ;
181+ Assert . IsTrue ( errors . Count > 0 ) ;
182+ Assert . IsTrue ( events . Count == 0 ) ;
183+ Assert . AreEqual ( model . Name , "Hello" ) ;
184+ Assert . IsFalse ( model . HasErrors ) ;
185+
186+ // Correct value, this should update the property
187+ Assert . IsTrue ( model . TrySetName ( "Hello world" , out errors ) ) ;
188+ Assert . IsTrue ( errors . Count == 0 ) ;
189+ Assert . IsTrue ( events . Count == 0 ) ;
190+ Assert . AreEqual ( model . Name , "Hello world" ) ;
191+ Assert . IsFalse ( model . HasErrors ) ;
192+
193+ // Actually set an invalid value to show some errors
194+ model . Name = "No" ;
195+
196+ // Errors should now be present
197+ Assert . IsTrue ( model . HasErrors ) ;
198+ Assert . IsTrue ( events . Count == 1 ) ;
199+ Assert . IsTrue ( model . GetErrors ( nameof ( Person . Name ) ) . Cast < ValidationResult > ( ) . Any ( ) ) ;
200+ Assert . IsTrue ( model . HasErrors ) ;
201+
202+ // Trying to set a correct property should clear the errors
203+ Assert . IsTrue ( model . TrySetName ( "This is fine" , out errors ) ) ;
204+ Assert . IsTrue ( errors . Count == 0 ) ;
205+ Assert . IsTrue ( events . Count == 2 ) ;
206+ Assert . IsFalse ( model . HasErrors ) ;
207+ Assert . AreEqual ( model . Name , "This is fine" ) ;
208+ }
209+
156210 public class Person : ObservableValidator
157211 {
158212 private string name ;
@@ -166,6 +220,11 @@ public string Name
166220 set => SetProperty ( ref this . name , value , true ) ;
167221 }
168222
223+ public bool TrySetName ( string value , out IReadOnlyCollection < ValidationResult > errors )
224+ {
225+ return TrySetProperty ( ref name , value , out errors , nameof ( Name ) ) ;
226+ }
227+
169228 private int age ;
170229
171230 [ Range ( 0 , 100 ) ]
0 commit comments