diff --git a/src/Markup/Perspex.Markup.Xaml/Data/Binding.cs b/src/Markup/Perspex.Markup.Xaml/Data/Binding.cs
index a99582cea7..5a3f647013 100644
--- a/src/Markup/Perspex.Markup.Xaml/Data/Binding.cs
+++ b/src/Markup/Perspex.Markup.Xaml/Data/Binding.cs
@@ -77,6 +77,11 @@ namespace Perspex.Markup.Xaml.Data
///
public object Source { get; set; }
+ ///
+ /// Gets or sets the validation methods for the binding to use.
+ ///
+ public ValidationMethods ValidationMethods { get; set; }
+
///
public InstancedBinding Initiate(
IPerspexObject target,
@@ -202,7 +207,7 @@ namespace Perspex.Markup.Xaml.Data
var result = new ExpressionObserver(
() => target.GetValue(Control.DataContextProperty),
path,
- update);
+ update, ValidationMethods);
return result;
}
@@ -213,7 +218,7 @@ namespace Perspex.Markup.Xaml.Data
.OfType()
.Select(x => x.GetObservable(Control.DataContextProperty))
.Switch(),
- path);
+ path, ValidationMethods);
}
}
@@ -223,7 +228,7 @@ namespace Perspex.Markup.Xaml.Data
var result = new ExpressionObserver(
ControlLocator.Track(target, elementName),
- path);
+ path, ValidationMethods);
return result;
}
@@ -231,7 +236,7 @@ namespace Perspex.Markup.Xaml.Data
{
Contract.Requires(source != null);
- return new ExpressionObserver(source, path);
+ return new ExpressionObserver(source, path, ValidationMethods);
}
private ExpressionObserver CreateTemplatedParentObserver(
diff --git a/src/Markup/Perspex.Markup.Xaml/MarkupExtensions/BindingExtension.cs b/src/Markup/Perspex.Markup.Xaml/MarkupExtensions/BindingExtension.cs
index 1e996b2b2a..d0dcd069a3 100644
--- a/src/Markup/Perspex.Markup.Xaml/MarkupExtensions/BindingExtension.cs
+++ b/src/Markup/Perspex.Markup.Xaml/MarkupExtensions/BindingExtension.cs
@@ -29,6 +29,7 @@ namespace Perspex.Markup.Xaml.MarkupExtensions
Mode = Mode,
Path = Path,
Priority = Priority,
+ ValidationMethods = ValidationMethods
};
}
@@ -40,5 +41,6 @@ namespace Perspex.Markup.Xaml.MarkupExtensions
public string Path { get; set; }
public BindingPriority Priority { get; set; } = BindingPriority.LocalValue;
public object Source { get; set; }
+ public ValidationMethods ValidationMethods { get; set; } = ValidationMethods.None;
}
}
\ No newline at end of file
diff --git a/src/Markup/Perspex.Markup/Data/CommonPropertyNames.cs b/src/Markup/Perspex.Markup/Data/CommonPropertyNames.cs
index 5866539886..5082a89862 100644
--- a/src/Markup/Perspex.Markup/Data/CommonPropertyNames.cs
+++ b/src/Markup/Perspex.Markup/Data/CommonPropertyNames.cs
@@ -1,8 +1,5 @@
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-using System.Threading.Tasks;
+// Copyright (c) The Perspex Project. All rights reserved.
+// Licensed under the MIT license. See licence.md file in the project root for full license information.
namespace Perspex.Markup.Data
{
diff --git a/src/Markup/Perspex.Markup/Data/ExpressionNode.cs b/src/Markup/Perspex.Markup/Data/ExpressionNode.cs
index e989a72177..b68c1ed426 100644
--- a/src/Markup/Perspex.Markup/Data/ExpressionNode.cs
+++ b/src/Markup/Perspex.Markup/Data/ExpressionNode.cs
@@ -105,6 +105,19 @@ namespace Perspex.Markup.Data
CurrentValue = reference;
}
+ protected virtual void SendValidationStatus(ValidationStatus status)
+ {
+ //Even if elements only bound to sub-values, send validation changes along so they will be surfaced to the UI level.
+ if (_subject != null)
+ {
+ _subject.OnNext(status);
+ }
+ else
+ {
+ Next?.SendValidationStatus(status);
+ }
+ }
+
protected virtual void Unsubscribe(object target)
{
}
diff --git a/src/Markup/Perspex.Markup/Data/ExpressionObserver.cs b/src/Markup/Perspex.Markup/Data/ExpressionObserver.cs
index e5b0d1ac78..d7fd25d237 100644
--- a/src/Markup/Perspex.Markup/Data/ExpressionObserver.cs
+++ b/src/Markup/Perspex.Markup/Data/ExpressionObserver.cs
@@ -28,6 +28,17 @@ namespace Perspex.Markup.Data
new InpcPropertyAccessorPlugin(),
};
+ ///
+ /// An ordered collection of validation checker plugins that can be used to customize
+ /// the validation of view model and model data.
+ ///
+ public static readonly IList ValidationCheckers =
+ new List
+ {
+ new IndeiValidationCheckerPlugin(),
+ new ExceptionValidationCheckerPlugin()
+ };
+
private readonly WeakReference _root;
private readonly Func