[C] do not return IsSet for BP with defaultVC (#2055)

BindableProperties with a defaultValueCreator are never in the default
(as defined by the defaultValue parameter) state. IsSet now reflects
that.

To allow styling properties with defaultVC, this adds a new flag in
BindableContextAttributes.
This commit is contained in:
Stephane Delcroix 2018-03-09 00:53:29 +01:00 коммит произвёл Jason Smith
Родитель 8403ef065b
Коммит 1741d7782c
2 изменённых файлов: 32 добавлений и 20 удалений

Просмотреть файл

@ -922,7 +922,7 @@ namespace Xamarin.Forms.Core.UnitTests
}
[Test]
public void IsSetIsFalseWhenPropSetByDefaultValueCreator()
public void IsSetIsTrueWhenPropSetByDefaultValueCreator()
{
string defaultValue = "default";
string defaultValueC = "defaultVC";
@ -939,7 +939,7 @@ namespace Xamarin.Forms.Core.UnitTests
Assert.AreEqual(defaultValueC, created);
var isSet = bindable.IsSet(bindableProperty);
Assert.IsFalse(isSet);
Assert.IsTrue(isSet);
}
[Test]

Просмотреть файл

@ -295,12 +295,10 @@ namespace Xamarin.Forms
if (binding == null)
throw new ArgumentNullException("binding");
BindablePropertyContext context = null;
if (fromStyle && (context = GetContext(targetProperty)) != null && (context.Attributes & BindableContextAttributes.IsDefaultValue) == 0 &&
(context.Attributes & BindableContextAttributes.IsSetFromStyle) == 0)
if (fromStyle && !CanBeSetFromStyle(targetProperty))
return;
context = context ?? GetOrCreateContext(targetProperty);
var context = GetOrCreateContext(targetProperty);
if (fromStyle)
context.Attributes |= BindableContextAttributes.IsSetFromStyle;
else
@ -318,6 +316,20 @@ namespace Xamarin.Forms
binding.Apply(BindingContext, this, targetProperty);
}
bool CanBeSetFromStyle(BindableProperty property)
{
var context = GetContext(property);
if (context == null)
return true;
if ((context.Attributes & BindableContextAttributes.IsSetFromStyle) == BindableContextAttributes.IsSetFromStyle)
return true;
if ((context.Attributes & BindableContextAttributes.IsDefaultValue) == BindableContextAttributes.IsDefaultValue)
return true;
if ((context.Attributes & BindableContextAttributes.IsDefaultValueCreated) == BindableContextAttributes.IsDefaultValueCreated)
return true;
return false;
}
internal void SetDynamicResource(BindableProperty property, string key)
{
SetDynamicResource(property, key, false);
@ -329,13 +341,10 @@ namespace Xamarin.Forms
throw new ArgumentNullException(nameof(property));
if (string.IsNullOrEmpty(key))
throw new ArgumentNullException(nameof(key));
BindablePropertyContext context = null;
if (fromStyle && (context = GetContext(property)) != null && (context.Attributes & BindableContextAttributes.IsDefaultValue) == 0 &&
(context.Attributes & BindableContextAttributes.IsSetFromStyle) == 0)
if (fromStyle && !CanBeSetFromStyle(property))
return;
context = context ?? GetOrCreateContext(property);
var context = GetOrCreateContext(property);
context.Attributes |= BindableContextAttributes.IsDynamicResource;
if (fromStyle)
@ -480,9 +489,7 @@ namespace Xamarin.Forms
if (bpcontext == null)
return;
if ( fromStyle && bpcontext != null
&& (bpcontext.Attributes & BindableContextAttributes.IsDefaultValue) != 0
&& (bpcontext.Attributes & BindableContextAttributes.IsSetFromStyle) == 0)
if (fromStyle && !CanBeSetFromStyle(property))
return;
object original = bpcontext.Value;
@ -499,7 +506,10 @@ namespace Xamarin.Forms
bpcontext.Attributes &= ~BindableContextAttributes.IsManuallySet;
bpcontext.Value = newValue;
bpcontext.Attributes |= BindableContextAttributes.IsDefaultValue;
if (property.DefaultValueCreator == null)
bpcontext.Attributes |= BindableContextAttributes.IsDefaultValue;
else
bpcontext.Attributes |= BindableContextAttributes.IsDefaultValueCreated;
if (!same)
{
@ -513,8 +523,10 @@ namespace Xamarin.Forms
{
var context = new BindablePropertyContext { Property = property, Value = property.DefaultValueCreator != null ? property.DefaultValueCreator(this) : property.DefaultValue };
if (property.DefaultValueCreator != null)
if (property.DefaultValueCreator == null)
context.Attributes = BindableContextAttributes.IsDefaultValue;
else
context.Attributes = BindableContextAttributes.IsDefaultValueCreated;
_properties.Add(context);
return context;
@ -565,9 +577,7 @@ namespace Xamarin.Forms
if (checkAccess && property.IsReadOnly)
throw new InvalidOperationException(string.Format("The BindableProperty \"{0}\" is readonly.", property.PropertyName));
BindablePropertyContext context = null;
if (fromStyle && (context = GetContext(property)) != null && (context.Attributes & BindableContextAttributes.IsDefaultValue) == 0 &&
(context.Attributes & BindableContextAttributes.IsSetFromStyle) == 0)
if (fromStyle && !CanBeSetFromStyle(property))
return;
SetValueCore(property, value, SetValueFlags.ClearOneWayBindings | SetValueFlags.ClearDynamicResource,
@ -597,6 +607,7 @@ namespace Xamarin.Forms
}
context.Attributes &= ~BindableContextAttributes.IsDefaultValue;
context.Attributes &= ~BindableContextAttributes.IsDefaultValueCreated;
if ((context.Attributes & BindableContextAttributes.IsDynamicResource) != 0 && clearDynamicResources)
RemoveDynamicResource(property);
@ -633,7 +644,8 @@ namespace Xamarin.Forms
IsBeingSet = 1 << 1,
IsDynamicResource = 1 << 2,
IsSetFromStyle = 1 << 3,
IsDefaultValue = 1 << 4
IsDefaultValue = 1 << 4,
IsDefaultValueCreated = 1 << 5,
}
class BindablePropertyContext