8 changed files with 204 additions and 2 deletions
@ -0,0 +1,52 @@ |
|||
using System; |
|||
using System.Collections.Generic; |
|||
using System.Linq; |
|||
using System.Text; |
|||
using System.Threading.Tasks; |
|||
using Perspex.Data; |
|||
|
|||
namespace Perspex.Markup.Data.Plugins |
|||
{ |
|||
public class ExceptionValidationCheckerPlugin : IValidationCheckerPlugin |
|||
{ |
|||
public ValidationCheckerBase Start(WeakReference reference, string name, IPropertyAccessor accessor, Action<ValidationStatus> callback) |
|||
{ |
|||
return new ExceptionValidationChecker(reference, name, accessor, callback); |
|||
} |
|||
|
|||
private class ExceptionValidationChecker : ValidationCheckerBase |
|||
{ |
|||
public ExceptionValidationChecker(WeakReference reference, string name, IPropertyAccessor accessor, Action<ValidationStatus> callback) |
|||
: base(reference, name, accessor, callback) |
|||
{ |
|||
} |
|||
|
|||
public override bool SetValue(object value, BindingPriority priority) |
|||
{ |
|||
try |
|||
{ |
|||
var success = base.SetValue(value, priority); |
|||
SendValidationCallback(new ExceptionValidationStatus(null)); |
|||
return success; |
|||
} |
|||
catch (Exception ex) |
|||
{ |
|||
SendValidationCallback(new ExceptionValidationStatus(ex)); |
|||
} |
|||
return false; |
|||
} |
|||
} |
|||
|
|||
private class ExceptionValidationStatus : ValidationStatus |
|||
{ |
|||
public ExceptionValidationStatus(Exception exception) |
|||
{ |
|||
Exception = exception; |
|||
} |
|||
|
|||
public Exception Exception { get; } |
|||
|
|||
public override bool IsValid => Exception != null; |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,14 @@ |
|||
using Perspex.Data; |
|||
using System; |
|||
using System.Collections.Generic; |
|||
using System.Linq; |
|||
using System.Text; |
|||
using System.Threading.Tasks; |
|||
|
|||
namespace Perspex.Markup.Data.Plugins |
|||
{ |
|||
public interface IValidationCheckerPlugin |
|||
{ |
|||
ValidationCheckerBase Start(WeakReference reference, string name, IPropertyAccessor accessor, Action<ValidationStatus> callback); |
|||
} |
|||
} |
|||
@ -0,0 +1,73 @@ |
|||
using System; |
|||
using System.Collections.Generic; |
|||
using System.Linq; |
|||
using System.Text; |
|||
using System.Threading.Tasks; |
|||
using Perspex.Data; |
|||
using System.ComponentModel; |
|||
using System.Collections; |
|||
using Perspex.Utilities; |
|||
|
|||
namespace Perspex.Markup.Data.Plugins |
|||
{ |
|||
class IndeiValidationCheckerPlugin : IValidationCheckerPlugin |
|||
{ |
|||
public ValidationCheckerBase Start(WeakReference reference, string name, IPropertyAccessor accessor, Action<ValidationStatus> callback) |
|||
{ |
|||
return new IndeiValidationChecker(reference, name, accessor, callback); |
|||
} |
|||
|
|||
private class IndeiValidationChecker : ValidationCheckerBase, IWeakSubscriber<DataErrorsChangedEventArgs> |
|||
{ |
|||
public IndeiValidationChecker(WeakReference reference, string name, IPropertyAccessor accessor, Action<ValidationStatus> callback) |
|||
: base(reference, name, accessor, callback) |
|||
{ |
|||
var target = reference.Target as INotifyDataErrorInfo; |
|||
if (target != null) |
|||
{ |
|||
if (target.HasErrors) |
|||
{ |
|||
SendValidationCallback(new IndeiValidationStatus(target.GetErrors(name))); |
|||
} |
|||
WeakSubscriptionManager.Subscribe( |
|||
target, |
|||
nameof(target.ErrorsChanged), |
|||
this); |
|||
} |
|||
} |
|||
|
|||
public override void Dispose() |
|||
{ |
|||
base.Dispose(); |
|||
var target = _reference.Target as INotifyDataErrorInfo; |
|||
if (target != null) |
|||
{ |
|||
WeakSubscriptionManager.Unsubscribe( |
|||
target, |
|||
nameof(target.ErrorsChanged), |
|||
this); |
|||
} |
|||
} |
|||
|
|||
public void OnEvent(object sender, DataErrorsChangedEventArgs e) |
|||
{ |
|||
if (e.PropertyName == _name || string.IsNullOrEmpty(e.PropertyName)) |
|||
{ |
|||
var indei = _reference.Target as INotifyDataErrorInfo; |
|||
SendValidationCallback(new IndeiValidationStatus(indei.GetErrors(e.PropertyName))); |
|||
} |
|||
} |
|||
} |
|||
|
|||
private class IndeiValidationStatus : ValidationStatus |
|||
{ |
|||
public IndeiValidationStatus(IEnumerable errors) |
|||
{ |
|||
Errors = errors; |
|||
} |
|||
public override bool IsValid => !Errors.OfType<object>().Any(); |
|||
|
|||
public IEnumerable Errors { get; } |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,34 @@ |
|||
using System; |
|||
using Perspex.Data; |
|||
|
|||
namespace Perspex.Markup.Data.Plugins |
|||
{ |
|||
public abstract class ValidationCheckerBase : IPropertyAccessor |
|||
{ |
|||
protected readonly WeakReference _reference; |
|||
protected readonly string _name; |
|||
private readonly IPropertyAccessor _accessor; |
|||
private readonly Action<ValidationStatus> _callback; |
|||
|
|||
protected ValidationCheckerBase(WeakReference reference, string name, IPropertyAccessor accessor, Action<ValidationStatus> callback) |
|||
{ |
|||
_reference = reference; |
|||
_name = name; |
|||
_accessor = accessor; |
|||
_callback = callback; |
|||
} |
|||
|
|||
public Type PropertyType => _accessor.PropertyType; |
|||
|
|||
public object Value => _accessor.Value; |
|||
|
|||
public virtual void Dispose() => _accessor.Dispose(); |
|||
|
|||
public virtual bool SetValue(object value, BindingPriority priority) => _accessor.SetValue(value, priority); |
|||
|
|||
protected void SendValidationCallback(ValidationStatus status) |
|||
{ |
|||
_callback?.Invoke(status); |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,20 @@ |
|||
// 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.
|
|||
|
|||
using System; |
|||
using System.Collections.Generic; |
|||
using System.Linq; |
|||
using System.Text; |
|||
using System.Threading.Tasks; |
|||
|
|||
namespace Perspex.Data |
|||
{ |
|||
/// <summary>
|
|||
/// Contains information on if the current object passed validation.
|
|||
/// Subclasses of this class contain additional information depending on the method of validation checking.
|
|||
/// </summary>
|
|||
public abstract class ValidationStatus |
|||
{ |
|||
public abstract bool IsValid { get; } |
|||
} |
|||
} |
|||
Loading…
Reference in new issue