diff options
Diffstat (limited to 'Xamarin.Forms.Core/Interactivity/PropertyCondition.cs')
-rw-r--r-- | Xamarin.Forms.Core/Interactivity/PropertyCondition.cs | 100 |
1 files changed, 100 insertions, 0 deletions
diff --git a/Xamarin.Forms.Core/Interactivity/PropertyCondition.cs b/Xamarin.Forms.Core/Interactivity/PropertyCondition.cs new file mode 100644 index 00000000..be37d48f --- /dev/null +++ b/Xamarin.Forms.Core/Interactivity/PropertyCondition.cs @@ -0,0 +1,100 @@ +using System; +using System.ComponentModel; +using System.Reflection; +using Xamarin.Forms.Xaml; + +namespace Xamarin.Forms +{ + public sealed class PropertyCondition : Condition, IValueProvider + { + readonly BindableProperty _stateProperty; + + BindableProperty _property; + object _triggerValue; + + public PropertyCondition() + { + _stateProperty = BindableProperty.CreateAttached("State", typeof(bool), typeof(DataTrigger), false, propertyChanged: OnStatePropertyChanged); + } + + public BindableProperty Property + { + get { return _property; } + set + { + if (_property == value) + return; + if (IsSealed) + throw new InvalidOperationException("Can not change Property once the Trigger has been applied."); + _property = value; + } + } + + public object Value + { + get { return _triggerValue; } + set + { + if (_triggerValue == value) + return; + if (IsSealed) + throw new InvalidOperationException("Can not change Value once the Trigger has been applied."); + _triggerValue = value; + } + } + + object IValueProvider.ProvideValue(IServiceProvider serviceProvider) + { + var valueconverter = serviceProvider.GetService(typeof(IValueConverterProvider)) as IValueConverterProvider; + Func<MemberInfo> minforetriever = () => Property.DeclaringType.GetRuntimeProperty(Property.PropertyName); + + object value = valueconverter.Convert(Value, Property.ReturnType, minforetriever, serviceProvider); + Value = value; + return this; + } + + internal override bool GetState(BindableObject bindable) + { + return (bool)bindable.GetValue(_stateProperty); + } + + internal override void SetUp(BindableObject bindable) + { + object newvalue = bindable.GetValue(Property); + + bool newState = (newvalue == Value) || (newvalue != null && newvalue.Equals(Value)); + bindable.SetValue(_stateProperty, newState); + bindable.PropertyChanged += OnAttachedObjectPropertyChanged; + } + + internal override void TearDown(BindableObject bindable) + { + bindable.ClearValue(_stateProperty); + bindable.PropertyChanged -= OnAttachedObjectPropertyChanged; + } + + void OnAttachedObjectPropertyChanged(object sender, PropertyChangedEventArgs e) + { + var bindable = (BindableObject)sender; + var oldState = (bool)bindable.GetValue(_stateProperty); + + if (Property == null) + return; + if (e.PropertyName != Property.PropertyName) + return; + object newvalue = bindable.GetValue(Property); + bool newstate = (newvalue == Value) || (newvalue != null && newvalue.Equals(Value)); + if (oldState != newstate) + bindable.SetValue(_stateProperty, newstate); + } + + void OnStatePropertyChanged(BindableObject bindable, object oldValue, object newValue) + { + if ((bool)oldValue == (bool)newValue) + return; + + if (ConditionChanged != null) + ConditionChanged(bindable, (bool)oldValue, (bool)newValue); + } + } +}
\ No newline at end of file |