Browse Source

Pass EnableDataValidation to ExpressionObserver.

pull/691/head
Steven Kirk 10 years ago
parent
commit
5a9371f786
  1. 9
      src/Avalonia.Base/AvaloniaObjectExtensions.cs
  2. 12
      src/Avalonia.Base/AvaloniaProperty.cs
  3. 4
      src/Avalonia.Base/Data/IBinding.cs
  4. 6
      src/Avalonia.Base/Data/IndexerBinding.cs
  5. 29
      src/Markup/Avalonia.Markup.Xaml/Data/Binding.cs
  6. 3
      src/Markup/Avalonia.Markup.Xaml/Data/MultiBinding.cs
  7. 3
      src/Markup/Avalonia.Markup.Xaml/Data/StyleResourceBinding.cs
  8. 2
      src/Markup/Avalonia.Markup.Xaml/MarkupExtensions/BindingExtension.cs
  9. 6
      tests/Avalonia.Controls.UnitTests/TextBoxTests_ValidationState.cs
  10. 4
      tests/Avalonia.Markup.Xaml.UnitTests/Data/BindingTests_Validation.cs
  11. 2
      tests/Avalonia.Styling.UnitTests/SetterTests.cs

9
src/Avalonia.Base/AvaloniaObjectExtensions.cs

@ -216,7 +216,11 @@ namespace Avalonia
Contract.Requires<ArgumentNullException>(property != null);
Contract.Requires<ArgumentNullException>(binding != null);
var result = binding.Initiate(target, property, anchor);
var result = binding.Initiate(
target,
property,
anchor,
property.GetMetadata(target.GetType()).EnabledDataValidation);
if (result != null)
{
@ -311,7 +315,8 @@ namespace Avalonia
public InstancedBinding Initiate(
IAvaloniaObject target,
AvaloniaProperty targetProperty,
object anchor = null)
object anchor = null,
bool enableDataValidation = false)
{
return new InstancedBinding(_source);
}

12
src/Avalonia.Base/AvaloniaProperty.cs

@ -275,7 +275,8 @@ namespace Avalonia
var metadata = new StyledPropertyMetadata<TValue>(
defaultValue,
validate: Cast(validate),
defaultBindingMode: defaultBindingMode);
defaultBindingMode: defaultBindingMode,
enableDataValidation: enableDataValidation);
var result = new StyledProperty<TValue>(
name,
@ -316,7 +317,8 @@ namespace Avalonia
var metadata = new StyledPropertyMetadata<TValue>(
defaultValue,
validate: Cast(validate),
defaultBindingMode: defaultBindingMode);
defaultBindingMode: defaultBindingMode,
enableDataValidation: enableDataValidation);
var result = new AttachedProperty<TValue>(name, typeof(TOwner), metadata, inherits);
AvaloniaPropertyRegistry.Instance.Register(typeof(THost), result);
@ -353,7 +355,8 @@ namespace Avalonia
var metadata = new StyledPropertyMetadata<TValue>(
defaultValue,
validate: Cast(validate),
defaultBindingMode: defaultBindingMode);
defaultBindingMode: defaultBindingMode,
enableDataValidation: enableDataValidation);
var result = new AttachedProperty<TValue>(name, ownerType, metadata, inherits);
AvaloniaPropertyRegistry.Instance.Register(typeof(THost), result);
@ -389,7 +392,8 @@ namespace Avalonia
var metadata = new DirectPropertyMetadata<TValue>(
unsetValue: unsetValue,
defaultBindingMode: defaultBindingMode);
defaultBindingMode: defaultBindingMode,
enableDataValidation: enableDataValidation);
var result = new DirectProperty<TOwner, TValue>(name, getter, setter, metadata);
AvaloniaPropertyRegistry.Instance.Register(typeof(TOwner), result);

4
src/Avalonia.Base/Data/IBinding.cs

@ -19,12 +19,14 @@ namespace Avalonia.Data
/// order to locate named controls or resources. The <paramref name="anchor"/> parameter
/// can be used to provice this context.
/// </param>
/// <param name="enableDataValidation">Whether data validation should be enabled.</param>
/// <returns>
/// A <see cref="InstancedBinding"/> or null if the binding could not be resolved.
/// </returns>
InstancedBinding Initiate(
IAvaloniaObject target,
AvaloniaProperty targetProperty,
object anchor = null);
object anchor = null,
bool enableDataValidation = false);
}
}

6
src/Avalonia.Base/Data/IndexerBinding.cs

@ -21,7 +21,11 @@ namespace Avalonia.Data
public AvaloniaProperty Property { get; }
private BindingMode Mode { get; }
public InstancedBinding Initiate(IAvaloniaObject target, AvaloniaProperty targetProperty, object anchor = null)
public InstancedBinding Initiate(
IAvaloniaObject target,
AvaloniaProperty targetProperty,
object anchor = null,
bool enableDataValidation = false)
{
var mode = Mode == BindingMode.Default ?
targetProperty.GetMetadata(target.GetType()).DefaultBindingMode :

29
src/Markup/Avalonia.Markup.Xaml/Data/Binding.cs

@ -78,16 +78,12 @@ namespace Avalonia.Markup.Xaml.Data
/// </summary>
public object Source { get; set; }
/// <summary>
/// Gets or sets a value indicating whether the property should be validated.
/// </summary>
public bool EnableValidation { get; set; }
/// <inheritdoc/>
public InstancedBinding Initiate(
IAvaloniaObject target,
AvaloniaProperty targetProperty,
object anchor = null)
object anchor = null,
bool enableDataValidation = false)
{
Contract.Requires<ArgumentNullException>(target != null);
@ -105,7 +101,7 @@ namespace Avalonia.Markup.Xaml.Data
}
else if (Source != null)
{
observer = CreateSourceObserver(Source, pathInfo.Path);
observer = CreateSourceObserver(Source, pathInfo.Path, enableDataValidation);
}
else if (RelativeSource == null || RelativeSource.Mode == RelativeSourceMode.DataContext)
{
@ -113,7 +109,8 @@ namespace Avalonia.Markup.Xaml.Data
target,
pathInfo.Path,
targetProperty == Control.DataContextProperty,
anchor);
anchor,
enableDataValidation);
}
else if (RelativeSource.Mode == RelativeSourceMode.TemplatedParent)
{
@ -197,7 +194,8 @@ namespace Avalonia.Markup.Xaml.Data
IAvaloniaObject target,
string path,
bool targetIsDataContext,
object anchor)
object anchor,
bool enableDataValidation)
{
Contract.Requires<ArgumentNullException>(target != null);
@ -220,7 +218,7 @@ namespace Avalonia.Markup.Xaml.Data
() => target.GetValue(Control.DataContextProperty),
path,
update,
EnableValidation);
enableDataValidation);
return result;
}
@ -229,7 +227,7 @@ namespace Avalonia.Markup.Xaml.Data
return new ExpressionObserver(
GetParentDataContext(target),
path,
EnableValidation);
enableDataValidation);
}
}
@ -240,15 +238,18 @@ namespace Avalonia.Markup.Xaml.Data
var result = new ExpressionObserver(
ControlLocator.Track(target, elementName),
path,
EnableValidation);
false);
return result;
}
private ExpressionObserver CreateSourceObserver(object source, string path)
private ExpressionObserver CreateSourceObserver(
object source,
string path,
bool enabledDataValidation)
{
Contract.Requires<ArgumentNullException>(source != null);
return new ExpressionObserver(source, path, EnableValidation);
return new ExpressionObserver(source, path, enabledDataValidation);
}
private ExpressionObserver CreateTemplatedParentObserver(

3
src/Markup/Avalonia.Markup.Xaml/Data/MultiBinding.cs

@ -53,7 +53,8 @@ namespace Avalonia.Markup.Xaml.Data
public InstancedBinding Initiate(
IAvaloniaObject target,
AvaloniaProperty targetProperty,
object anchor = null)
object anchor = null,
bool enableDataValidation = false)
{
if (Converter == null)
{

3
src/Markup/Avalonia.Markup.Xaml/Data/StyleResourceBinding.cs

@ -37,7 +37,8 @@ namespace Avalonia.Markup.Xaml.Data
public InstancedBinding Initiate(
IAvaloniaObject target,
AvaloniaProperty targetProperty,
object anchor = null)
object anchor = null,
bool enableDataValidation = false)
{
if (Name == "Red")
{

2
src/Markup/Avalonia.Markup.Xaml/MarkupExtensions/BindingExtension.cs

@ -29,7 +29,6 @@ namespace Avalonia.Markup.Xaml.MarkupExtensions
Mode = Mode,
Path = Path,
Priority = Priority,
EnableValidation = EnableValidation,
};
}
@ -41,6 +40,5 @@ namespace Avalonia.Markup.Xaml.MarkupExtensions
public string Path { get; set; }
public BindingPriority Priority { get; set; } = BindingPriority.LocalValue;
public object Source { get; set; }
public bool EnableValidation { get; set; }
}
}

6
tests/Avalonia.Controls.UnitTests/TextBoxTests_ValidationState.cs

@ -21,7 +21,7 @@ namespace Avalonia.Controls.UnitTests
var target = new TextBox();
var binding = new Binding(nameof(ExceptionTest.LessThan10));
binding.Source = new ExceptionTest();
binding.EnableValidation = true;
////binding.EnableValidation = true;
target.Bind(TextBox.TextProperty, binding);
Assert.True(false);
@ -41,7 +41,7 @@ namespace Avalonia.Controls.UnitTests
var target = new TextBox();
var binding = new Binding(nameof(ExceptionTest.LessThan10));
binding.Source = new ExceptionTest();
binding.EnableValidation = true;
////binding.EnableValidation = true;
target.Bind(TextBox.TextProperty, binding);
Assert.True(false);
@ -61,7 +61,7 @@ namespace Avalonia.Controls.UnitTests
var target = new TextBox();
var binding = new Binding(nameof(ExceptionTest.LessThan10));
binding.Source = new IndeiTest();
binding.EnableValidation = true;
////binding.EnableValidation = true;
target.Bind(TextBox.TextProperty, binding);
Assert.True(false);

4
tests/Avalonia.Markup.Xaml.UnitTests/Data/BindingTests_Validation.cs

@ -25,15 +25,15 @@ namespace Avalonia.Markup.Xaml.UnitTests.Data
}
[Fact]
public void Validated_Property_Does_Not_Receive_BindingNotifications()
public void Validated_Property_Receives_BindingNotifications()
{
var source = new ValidationTestModel { MustBePositive = 5 };
var target = new TestControl
{
DataContext = source,
[!TestControl.ValidatedProperty] = new Binding(nameof(source.MustBePositive)),
};
target.Bind(TestControl.ValidatedProperty, new Binding(nameof(source.MustBePositive)));
source.MustBePositive = 6;
Assert.Equal(

2
tests/Avalonia.Styling.UnitTests/SetterTests.cs

@ -27,7 +27,7 @@ namespace Avalonia.Styling.UnitTests
var control = new TextBlock();
var subject = new BehaviorSubject<object>("foo");
var descriptor = new InstancedBinding(subject);
var binding = Mock.Of<IBinding>(x => x.Initiate(control, TextBlock.TextProperty, null) == descriptor);
var binding = Mock.Of<IBinding>(x => x.Initiate(control, TextBlock.TextProperty, null, false) == descriptor);
var style = Mock.Of<IStyle>();
var setter = new Setter(TextBlock.TextProperty, binding);

Loading…
Cancel
Save