diff --git a/.create-nuget.bat b/.create-nuget.bat
index eaab54343..dbce3acdb 100644
--- a/.create-nuget.bat
+++ b/.create-nuget.bat
@@ -118,19 +118,27 @@ echo foo > Xamarin.Forms.Platform.UAP\bin\debug\FormsEmbeddedPageWrapper.xbf
if "%1" == "droid" (
%NUGET_EXE% restore .xamarin.forms.android.nuget.sln
- msbuild /v:m /p:platform="any cpu" .xamarin.forms.android.nuget.sln
+ msbuild /v:m /p:platform="any cpu" /p:WarningLevel=0 .xamarin.forms.android.nuget.sln
)
if "%1" == "ios" (
%NUGET_EXE% restore .xamarin.forms.ios.nuget.sln
msbuild /v:m /p:platform="any cpu" .xamarin.forms.ios.nuget.sln
)
+if "%1" == "droidios" (
+ %NUGET_EXE% restore .xamarin.forms.android.nuget.sln
+ %NUGET_EXE% restore .xamarin.forms.ios.nuget.sln
+ msbuild /v:m /p:platform="any cpu" /p:WarningLevel=0 .xamarin.forms.android.nuget.sln
+ msbuild /v:m /p:platform="any cpu" .xamarin.forms.ios.nuget.sln
+)
if "%1" == "uap" (
%NUGET_EXE% restore .xamarin.forms.uap.nuget.sln
+ msbuild /v:m /p:platform="any cpu" .xamarin.forms.uap.nuget.sln /t:restore
msbuild /v:m /p:platform="any cpu" .xamarin.forms.uap.nuget.sln
)
if "%1" == "all" (
%NUGET_EXE% restore .xamarin.forms.sln
- msbuild /v:m /p:platform="any cpu" .xamarin.forms.nuget.sln
+ msbuild /v:m /p:platform="any cpu" .xamarin.forms.uap.nuget.sln /t:restore
+ msbuild /v:m /p:platform="any cpu" /p:WarningLevel=0 .xamarin.forms.nuget.sln
)
if "%DEBUG_VERSION%"=="" set DEBUG_VERSION=0
diff --git a/EmbeddingTestBeds/Embedding.Droid/Embedding.Droid.csproj b/EmbeddingTestBeds/Embedding.Droid/Embedding.Droid.csproj
index 643c76cc2..bf235697b 100644
--- a/EmbeddingTestBeds/Embedding.Droid/Embedding.Droid.csproj
+++ b/EmbeddingTestBeds/Embedding.Droid/Embedding.Droid.csproj
@@ -19,13 +19,6 @@
Properties\AndroidManifest.xml
- false
-
-
- True
-
-
- False
True
diff --git a/PagesGallery/PagesGallery.Droid/PagesGallery.Droid.csproj b/PagesGallery/PagesGallery.Droid/PagesGallery.Droid.csproj
index 8b984ed0e..07af51a18 100644
--- a/PagesGallery/PagesGallery.Droid/PagesGallery.Droid.csproj
+++ b/PagesGallery/PagesGallery.Droid/PagesGallery.Droid.csproj
@@ -26,13 +26,6 @@
True
1G
- false
-
-
- True
-
-
- False
true
diff --git a/Stubs/Xamarin.Forms.Platform.Android/Xamarin.Forms.Platform.Android (Forwarders).csproj b/Stubs/Xamarin.Forms.Platform.Android/Xamarin.Forms.Platform.Android (Forwarders).csproj
index 67ee5d346..2600a433a 100644
--- a/Stubs/Xamarin.Forms.Platform.Android/Xamarin.Forms.Platform.Android (Forwarders).csproj
+++ b/Stubs/Xamarin.Forms.Platform.Android/Xamarin.Forms.Platform.Android (Forwarders).csproj
@@ -20,13 +20,6 @@
v8.1
- false
-
-
- True
-
-
- False
true
diff --git a/Xamarin.Forms.Build.Tasks/SetPropertiesVisitor.cs b/Xamarin.Forms.Build.Tasks/SetPropertiesVisitor.cs
index 9891d2cf7..cfeabe7c7 100644
--- a/Xamarin.Forms.Build.Tasks/SetPropertiesVisitor.cs
+++ b/Xamarin.Forms.Build.Tasks/SetPropertiesVisitor.cs
@@ -540,7 +540,7 @@ namespace Xamarin.Forms.Build.Tasks
static IEnumerable CompiledBindingGetSetter(TypeReference tSourceRef, TypeReference tPropertyRef, IList> properties, ElementNode node, ILContext context)
{
if (properties == null || properties.Count == 0) {
- yield return Instruction.Create(OpCodes.Ldnull);
+ yield return Create(Ldnull);
yield break;
}
@@ -573,7 +573,7 @@ namespace Xamarin.Forms.Build.Tasks
var lastProperty = properties.LastOrDefault();
var setterRef = lastProperty?.Item1.SetMethod;
if (setterRef == null) {
- yield return Instruction.Create(OpCodes.Ldnull); //throw or not ?
+ yield return Create(Ldnull); //throw or not ?
yield break;
}
@@ -586,12 +586,12 @@ namespace Xamarin.Forms.Build.Tasks
var indexerArg = properties[i].Item2;
if (indexerArg != null) {
if (property.GetMethod.Parameters [0].ParameterType == module.TypeSystem.String)
- il.Emit(OpCodes.Ldstr, indexerArg);
+ il.Emit(Ldstr, indexerArg);
else if (property.GetMethod.Parameters [0].ParameterType == module.TypeSystem.Int32) {
int index;
if (!int.TryParse(indexerArg, out index))
throw new XamlParseException($"Binding: {indexerArg} could not be parsed as an index for a {property.Name}", node as IXmlLineInfo);
- il.Emit(OpCodes.Ldc_I4, index);
+ il.Emit(Ldc_I4, index);
}
}
if (property.GetMethod.IsVirtual)
@@ -603,25 +603,23 @@ namespace Xamarin.Forms.Build.Tasks
var indexer = properties.Last().Item2;
if (indexer != null) {
if (lastProperty.Item1.GetMethod.Parameters [0].ParameterType == module.TypeSystem.String)
- il.Emit(OpCodes.Ldstr, indexer);
+ il.Emit(Ldstr, indexer);
else if (lastProperty.Item1.GetMethod.Parameters [0].ParameterType == module.TypeSystem.Int32) {
int index;
if (!int.TryParse(indexer, out index))
throw new XamlParseException($"Binding: {indexer} could not be parsed as an index for a {lastProperty.Item1.Name}", node as IXmlLineInfo);
- il.Emit(OpCodes.Ldc_I4, index);
+ il.Emit(Ldc_I4, index);
}
}
- if (tPropertyRef.IsValueType)
- il.Emit(Ldarga_S, (byte)1);
- else
- il.Emit(Ldarg_1);
+
+ il.Emit(Ldarg_1);
if (setterRef.IsVirtual)
il.Emit(Callvirt, module.ImportReference(setterRef));
else
il.Emit(Call, module.ImportReference(setterRef));
- il.Emit(OpCodes.Ret);
+ il.Emit(Ret);
context.Body.Method.DeclaringType.Methods.Add(setter);
diff --git a/Xamarin.Forms.ControlGallery.Android/Properties/AndroidManifest.xml b/Xamarin.Forms.ControlGallery.Android/Properties/AndroidManifest.xml
index 6b7581d53..611abb2f8 100644
--- a/Xamarin.Forms.ControlGallery.Android/Properties/AndroidManifest.xml
+++ b/Xamarin.Forms.ControlGallery.Android/Properties/AndroidManifest.xml
@@ -1,6 +1,6 @@
-
+
diff --git a/Xamarin.Forms.ControlGallery.Android/Xamarin.Forms.ControlGallery.Android.csproj b/Xamarin.Forms.ControlGallery.Android/Xamarin.Forms.ControlGallery.Android.csproj
index 35885b65b..f518bb038 100644
--- a/Xamarin.Forms.ControlGallery.Android/Xamarin.Forms.ControlGallery.Android.csproj
+++ b/Xamarin.Forms.ControlGallery.Android/Xamarin.Forms.ControlGallery.Android.csproj
@@ -29,13 +29,6 @@
1G
- false
-
-
- True
-
-
- False
True
diff --git a/Xamarin.Forms.Controls.Issues/Xamarin.Forms.Controls.Issues.Shared/Issue3524.cs b/Xamarin.Forms.Controls.Issues/Xamarin.Forms.Controls.Issues.Shared/Issue3524.cs
new file mode 100644
index 000000000..efa593b09
--- /dev/null
+++ b/Xamarin.Forms.Controls.Issues/Xamarin.Forms.Controls.Issues.Shared/Issue3524.cs
@@ -0,0 +1,77 @@
+using System;
+using System.Collections.Generic;
+using System.Collections.ObjectModel;
+using System.Text;
+using System.Threading.Tasks;
+using Xamarin.Forms.CustomAttributes;
+using Xamarin.Forms.Internals;
+
+
+#if UITEST
+using Xamarin.UITest;
+using NUnit.Framework;
+using Xamarin.Forms.Core.UITests;
+#endif
+
+namespace Xamarin.Forms.Controls.Issues
+{
+ [Preserve(AllMembers = true)]
+ [Issue(IssueTracker.Github, 3524, "ICommand binding from a TapGestureRecognizer on a Span doesn't work")]
+#if UITEST
+ [NUnit.Framework.Category(UITestCategories.Gestures)]
+#endif
+ public class Issue3524 : TestContentPage
+ {
+ const string kText = "Click Me To Increment";
+
+ public Command TapCommand { get; set; }
+ public String Text { get; set; } = kText;
+
+ protected override void Init()
+ {
+ int i = 0;
+
+ FormattedString formattedString = new FormattedString();
+ var span = new Span() { AutomationId = kText };
+ span.Text = kText;
+ var tapGesture = new TapGestureRecognizer();
+ tapGesture.SetBinding(TapGestureRecognizer.CommandProperty, "TapCommand");
+ span.GestureRecognizers.Add(tapGesture);
+ formattedString.Spans.Add(span);
+ BindingContext = this;
+ var label = new Label()
+ {
+ AutomationId = kText,
+ HorizontalOptions = LayoutOptions.Center
+ };
+
+ label.FormattedText = formattedString;
+ TapCommand = new Command(() =>
+ {
+ i++;
+ span.Text = $"{kText}: {i}";
+ });
+
+ Content = new ContentView()
+ {
+ Content = new StackLayout()
+ {
+ Children =
+ {
+ label
+ }
+ }
+ };
+ }
+
+#if UITEST
+ [Test]
+ public void SpanGestureCommand()
+ {
+ RunningApp.WaitForElement(kText);
+ RunningApp.Tap(kText);
+ RunningApp.WaitForElement($"{kText}: 1");
+ }
+#endif
+ }
+}
diff --git a/Xamarin.Forms.Controls.Issues/Xamarin.Forms.Controls.Issues.Shared/Xamarin.Forms.Controls.Issues.Shared.projitems b/Xamarin.Forms.Controls.Issues/Xamarin.Forms.Controls.Issues.Shared/Xamarin.Forms.Controls.Issues.Shared.projitems
index f8e165d6a..b0c20a401 100644
--- a/Xamarin.Forms.Controls.Issues/Xamarin.Forms.Controls.Issues.Shared/Xamarin.Forms.Controls.Issues.Shared.projitems
+++ b/Xamarin.Forms.Controls.Issues/Xamarin.Forms.Controls.Issues.Shared/Xamarin.Forms.Controls.Issues.Shared.projitems
@@ -8,7 +8,8 @@
Xamarin.Forms.Controls.Issues
-
+
+
diff --git a/Xamarin.Forms.Core/BindableObjectExtensions.cs b/Xamarin.Forms.Core/BindableObjectExtensions.cs
index fec2ad881..2a54dec95 100644
--- a/Xamarin.Forms.Core/BindableObjectExtensions.cs
+++ b/Xamarin.Forms.Core/BindableObjectExtensions.cs
@@ -1,10 +1,33 @@
using System;
+using System.Collections.Generic;
using System.Linq.Expressions;
namespace Xamarin.Forms
{
public static class BindableObjectExtensions
{
+ internal static void PropagateBindingContext(this BindableObject self, IList children)
+ {
+ PropagateBindingContext(self, children, BindableObject.SetInheritedBindingContext);
+ }
+
+ internal static void PropagateBindingContext(this BindableObject self, IList children, Action setChildBindingContext)
+ {
+ if (children == null || children.Count == 0)
+ return;
+
+ var bc = self.BindingContext;
+
+ for (var i = 0; i < children.Count; i++)
+ {
+ var bo = children[i] as BindableObject;
+ if (bo == null)
+ continue;
+
+ setChildBindingContext(bo, bc);
+ }
+ }
+
public static void SetBinding(this BindableObject self, BindableProperty targetProperty, string path, BindingMode mode = BindingMode.Default, IValueConverter converter = null,
string stringFormat = null)
{
diff --git a/Xamarin.Forms.Core/Element.cs b/Xamarin.Forms.Core/Element.cs
index 79c6bc928..c9ffe1149 100644
--- a/Xamarin.Forms.Core/Element.cs
+++ b/Xamarin.Forms.Core/Element.cs
@@ -319,21 +319,10 @@ namespace Xamarin.Forms
protected override void OnBindingContextChanged()
{
- var gotBindingContext = false;
- object bc = null;
-
- for (var index = 0; index < LogicalChildrenInternal.Count; index++)
+ this.PropagateBindingContext(LogicalChildrenInternal, (child, bc) =>
{
- Element child = LogicalChildrenInternal[index];
-
- if (!gotBindingContext)
- {
- bc = BindingContext;
- gotBindingContext = true;
- }
-
- SetChildInheritedBindingContext(child, bc);
- }
+ SetChildInheritedBindingContext((Element)child, bc);
+ });
if (_bindableResources != null)
foreach (BindableObject item in _bindableResources)
diff --git a/Xamarin.Forms.Core/Span.cs b/Xamarin.Forms.Core/Span.cs
index fbf42081a..7960e6f62 100644
--- a/Xamarin.Forms.Core/Span.cs
+++ b/Xamarin.Forms.Core/Span.cs
@@ -103,11 +103,18 @@ namespace Xamarin.Forms
set { SetValue(TextDecorationsProperty, value); }
}
- public double LineHeight {
+ public double LineHeight
+ {
get { return (double)GetValue(LineHeightElement.LineHeightProperty); }
set { SetValue(LineHeightElement.LineHeightProperty, value); }
}
+ protected override void OnBindingContextChanged()
+ {
+ this.PropagateBindingContext(GestureRecognizers);
+ base.OnBindingContextChanged();
+ }
+
void IFontElement.OnFontFamilyChanged(string oldValue, string newValue)
{
}
diff --git a/Xamarin.Forms.Core/View.cs b/Xamarin.Forms.Core/View.cs
index b513ae7da..7962212c9 100644
--- a/Xamarin.Forms.Core/View.cs
+++ b/Xamarin.Forms.Core/View.cs
@@ -154,24 +154,7 @@ namespace Xamarin.Forms
protected override void OnBindingContextChanged()
{
- var gotBindingContext = false;
- object bc = null;
-
- for (var i = 0; i < GestureRecognizers.Count; i++)
- {
- var bo = GestureRecognizers[i] as BindableObject;
- if (bo == null)
- continue;
-
- if (!gotBindingContext)
- {
- bc = BindingContext;
- gotBindingContext = true;
- }
-
- SetInheritedBindingContext(bo, bc);
- }
-
+ this.PropagateBindingContext(GestureRecognizers);
base.OnBindingContextChanged();
}
diff --git a/Xamarin.Forms.Core/Xamarin.Forms.Core.csproj b/Xamarin.Forms.Core/Xamarin.Forms.Core.csproj
index cfaf9193b..d585a8630 100644
--- a/Xamarin.Forms.Core/Xamarin.Forms.Core.csproj
+++ b/Xamarin.Forms.Core/Xamarin.Forms.Core.csproj
@@ -21,7 +21,7 @@
-
+
diff --git a/Xamarin.Forms.Maps.Android/Xamarin.Forms.Maps.Android.csproj b/Xamarin.Forms.Maps.Android/Xamarin.Forms.Maps.Android.csproj
index 90fbd294b..43cbaaae8 100644
--- a/Xamarin.Forms.Maps.Android/Xamarin.Forms.Maps.Android.csproj
+++ b/Xamarin.Forms.Maps.Android/Xamarin.Forms.Maps.Android.csproj
@@ -20,13 +20,6 @@
true
- false
-
-
- True
-
-
- False
true
diff --git a/Xamarin.Forms.Platform.Android.AppLinks/Xamarin.Forms.Platform.Android.AppLinks.csproj b/Xamarin.Forms.Platform.Android.AppLinks/Xamarin.Forms.Platform.Android.AppLinks.csproj
index 408d6ee67..3cd5a094d 100644
--- a/Xamarin.Forms.Platform.Android.AppLinks/Xamarin.Forms.Platform.Android.AppLinks.csproj
+++ b/Xamarin.Forms.Platform.Android.AppLinks/Xamarin.Forms.Platform.Android.AppLinks.csproj
@@ -16,13 +16,6 @@
v8.1
- false
-
-
- True
-
-
- False
true
diff --git a/Xamarin.Forms.Platform.Android.FormsViewGroup/Xamarin.Forms.Platform.Android.FormsViewGroup.csproj b/Xamarin.Forms.Platform.Android.FormsViewGroup/Xamarin.Forms.Platform.Android.FormsViewGroup.csproj
index d12511a44..9d6b90e7c 100644
--- a/Xamarin.Forms.Platform.Android.FormsViewGroup/Xamarin.Forms.Platform.Android.FormsViewGroup.csproj
+++ b/Xamarin.Forms.Platform.Android.FormsViewGroup/Xamarin.Forms.Platform.Android.FormsViewGroup.csproj
@@ -2,8 +2,6 @@
XAJavaInterop1
- v8.1
- false
Debug
@@ -19,12 +17,6 @@
512
v7.0
-
- True
-
-
- False
-
true
full
diff --git a/Xamarin.Forms.Platform.Android/AppCompat/MasterDetailPageRenderer.cs b/Xamarin.Forms.Platform.Android/AppCompat/MasterDetailPageRenderer.cs
index 18b8247c2..6771a1798 100644
--- a/Xamarin.Forms.Platform.Android/AppCompat/MasterDetailPageRenderer.cs
+++ b/Xamarin.Forms.Platform.Android/AppCompat/MasterDetailPageRenderer.cs
@@ -1,3 +1,4 @@
+
using System;
using System.ComponentModel;
using System.Threading.Tasks;
@@ -247,7 +248,7 @@ namespace Xamarin.Forms.Platform.Android.AppCompat
protected override void OnDetachedFromWindow()
{
base.OnDetachedFromWindow();
- PageController.SendDisappearing();
+ PageController?.SendDisappearing();
}
protected virtual void OnElementChanged(VisualElement oldElement, VisualElement newElement)
diff --git a/Xamarin.Forms.Platform.Android/AppCompat/Platform.cs b/Xamarin.Forms.Platform.Android/AppCompat/Platform.cs
index 1e8d1d426..d69e8ec38 100644
--- a/Xamarin.Forms.Platform.Android/AppCompat/Platform.cs
+++ b/Xamarin.Forms.Platform.Android/AppCompat/Platform.cs
@@ -273,8 +273,10 @@ namespace Xamarin.Forms.Platform.Android.AppCompat
for (int i = 0; i < _renderer.ChildCount; i++)
viewsToRemove.Add(_renderer.GetChildAt(i));
- foreach (var root in _navModel.Roots)
- renderersToDispose.Add(Android.Platform.GetRenderer(root));
+ foreach (IVisualElementRenderer rootRenderer in _navModel.Roots.Select(Android.Platform.GetRenderer))
+ {
+ rootRenderer?.Dispose();
+ }
_navModel = new NavigationModel();
diff --git a/Xamarin.Forms.Platform.Android/Platform.cs b/Xamarin.Forms.Platform.Android/Platform.cs
index 407e3aedc..1f3db479c 100644
--- a/Xamarin.Forms.Platform.Android/Platform.cs
+++ b/Xamarin.Forms.Platform.Android/Platform.cs
@@ -341,7 +341,7 @@ namespace Xamarin.Forms.Platform.Android
public static IVisualElementRenderer GetRenderer(VisualElement bindable)
{
- return (IVisualElementRenderer)bindable.GetValue(RendererProperty);
+ return (IVisualElementRenderer)bindable?.GetValue(RendererProperty);
}
public static void SetRenderer(VisualElement bindable, IVisualElementRenderer value)
diff --git a/Xamarin.Forms.Platform.Android/Renderers/LabelRenderer.cs b/Xamarin.Forms.Platform.Android/Renderers/LabelRenderer.cs
index ac46a2953..97dc6b152 100644
--- a/Xamarin.Forms.Platform.Android/Renderers/LabelRenderer.cs
+++ b/Xamarin.Forms.Platform.Android/Renderers/LabelRenderer.cs
@@ -217,6 +217,7 @@ namespace Xamarin.Forms.Platform.Android
void UpdateLineHeight()
{
+ _lastSizeRequest = null;
if (Element.LineHeight == -1)
_view.SetLineSpacing(_lineSpacingExtraDefault, _lineSpacingMultiplierDefault);
else if (Element.LineHeight >= 0)
diff --git a/Xamarin.Forms.Platform.Android/Xamarin.Forms.Platform.Android.csproj b/Xamarin.Forms.Platform.Android/Xamarin.Forms.Platform.Android.csproj
index 400b7a56f..48104074a 100644
--- a/Xamarin.Forms.Platform.Android/Xamarin.Forms.Platform.Android.csproj
+++ b/Xamarin.Forms.Platform.Android/Xamarin.Forms.Platform.Android.csproj
@@ -22,12 +22,6 @@
-
- True
-
-
- False
-
true
full
diff --git a/Xamarin.Forms.Platform.UAP/LabelRenderer.cs b/Xamarin.Forms.Platform.UAP/LabelRenderer.cs
index e63eeea76..22342e8ce 100644
--- a/Xamarin.Forms.Platform.UAP/LabelRenderer.cs
+++ b/Xamarin.Forms.Platform.UAP/LabelRenderer.cs
@@ -142,6 +142,7 @@ namespace Xamarin.Forms.Platform.UWP
UpdateLineBreakMode(Control);
UpdateMaxLines(Control);
UpdateDetectReadingOrderFromContent(Control);
+ UpdateLineHeight(Control);
}
}
diff --git a/Xamarin.Forms.Platform.iOS/Extensions/LabelExtensions.cs b/Xamarin.Forms.Platform.iOS/Extensions/LabelExtensions.cs
index e634ef187..6095a7494 100644
--- a/Xamarin.Forms.Platform.iOS/Extensions/LabelExtensions.cs
+++ b/Xamarin.Forms.Platform.iOS/Extensions/LabelExtensions.cs
@@ -59,7 +59,7 @@ namespace Xamarin.Forms.Platform.MacOS
var span = element.FormattedText.Spans[i];
var location = currentLocation;
- var length = span.Text.Length;
+ var length = span.Text?.Length ?? 0;
if (length == 0)
continue;
diff --git a/Xamarin.Forms.Xaml.UnitTests/Issues/Gh3539.xaml b/Xamarin.Forms.Xaml.UnitTests/Issues/Gh3539.xaml
new file mode 100644
index 000000000..a6b9da7c5
--- /dev/null
+++ b/Xamarin.Forms.Xaml.UnitTests/Issues/Gh3539.xaml
@@ -0,0 +1,22 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/Xamarin.Forms.Xaml.UnitTests/Issues/Gh3539.xaml.cs b/Xamarin.Forms.Xaml.UnitTests/Issues/Gh3539.xaml.cs
new file mode 100644
index 000000000..24824949d
--- /dev/null
+++ b/Xamarin.Forms.Xaml.UnitTests/Issues/Gh3539.xaml.cs
@@ -0,0 +1,214 @@
+using System;
+using System.Collections.Generic;
+using System.ComponentModel;
+using System.Reflection;
+using System.Text;
+using NUnit.Framework;
+using Xamarin.Forms;
+using Xamarin.Forms.Core.UnitTests;
+
+namespace Xamarin.Forms.Xaml.UnitTests
+{
+ public class Gh3539ViewModel : INotifyPropertyChanged
+ {
+ Color color;
+ string name;
+
+ public event PropertyChangedEventHandler PropertyChanged;
+
+ public double Hue {
+ set {
+ if (color.Hue != value) {
+ Color = Color.FromHsla(value, color.Saturation, color.Luminosity);
+ }
+ }
+ get {
+ return color.Hue;
+ }
+ }
+
+ public double Saturation {
+ set {
+ if (color.Saturation != value) {
+ Color = Color.FromHsla(color.Hue, value, color.Luminosity);
+ }
+ }
+ get {
+ return color.Saturation;
+ }
+ }
+
+ public double Luminosity {
+ set {
+ if (color.Luminosity != value) {
+ Color = Color.FromHsla(color.Hue, color.Saturation, value);
+ }
+ }
+ get {
+ return color.Luminosity;
+ }
+ }
+
+ public Color Color {
+ set {
+ if (color != value) {
+ color = value;
+ PropertyChanged?.Invoke(this, new PropertyChangedEventArgs("Hue"));
+ PropertyChanged?.Invoke(this, new PropertyChangedEventArgs("Saturation"));
+ PropertyChanged?.Invoke(this, new PropertyChangedEventArgs("Luminosity"));
+ PropertyChanged?.Invoke(this, new PropertyChangedEventArgs("Color"));
+
+ Name = Gh3539NamedColor.GetNearestColorName(color);
+ }
+ }
+ get {
+ return color;
+ }
+ }
+
+ public string Name {
+ private set {
+ if (name != value) {
+ name = value;
+ PropertyChanged?.Invoke(this, new PropertyChangedEventArgs("Name"));
+ }
+ }
+ get {
+ return name;
+ }
+ }
+ }
+
+ public class Gh3539NamedColor : IEquatable, IComparable
+ {
+ // Instance members
+ private Gh3539NamedColor()
+ {
+ }
+
+ public string Name { private set; get; }
+
+ public string FriendlyName { private set; get; }
+
+ public Color Color { private set; get; }
+
+ public string RgbDisplay { private set; get; }
+
+ public bool Equals(Gh3539NamedColor other)
+ {
+ return Name.Equals(other.Name);
+ }
+
+ public int CompareTo(Gh3539NamedColor other)
+ {
+ return Name.CompareTo(other.Name);
+ }
+
+ // Static members
+ static Gh3539NamedColor()
+ {
+ List all = new List();
+ StringBuilder stringBuilder = new StringBuilder();
+
+ // Loop through the public static fields of the Color structure.
+ foreach (FieldInfo fieldInfo in typeof(Color).GetRuntimeFields()) {
+ if (fieldInfo.IsPublic &&
+ fieldInfo.IsStatic &&
+ fieldInfo.FieldType == typeof(Color)) {
+ // Convert the name to a friendly name.
+ string name = fieldInfo.Name;
+ stringBuilder.Clear();
+ int index = 0;
+
+ foreach (char ch in name) {
+ if (index != 0 && Char.IsUpper(ch)) {
+ stringBuilder.Append(' ');
+ }
+ stringBuilder.Append(ch);
+ index++;
+ }
+
+ // Instantiate a NamedColor object.
+ Color color = (Color)fieldInfo.GetValue(null);
+
+ Gh3539NamedColor namedColor = new Gh3539NamedColor {
+ Name = name,
+ FriendlyName = stringBuilder.ToString(),
+ Color = color,
+ RgbDisplay = String.Format("{0:X2}-{1:X2}-{2:X2}",
+ (int)(255 * color.R),
+ (int)(255 * color.G),
+ (int)(255 * color.B))
+ };
+
+ // Add it to the collection.
+ all.Add(namedColor);
+ }
+ }
+ all.TrimExcess();
+ all.Sort();
+ All = all;
+ }
+
+ public static IList All { private set; get; }
+
+ public static Gh3539NamedColor Find(string name)
+ {
+ return ((List)All).Find(nc => nc.Name == name);
+ }
+
+ public static string GetNearestColorName(Color color)
+ {
+ double shortestDistance = 1000;
+ Gh3539NamedColor closestColor = null;
+
+ foreach (Gh3539NamedColor namedColor in Gh3539NamedColor.All) {
+ double distance = Math.Sqrt(Math.Pow(color.R - namedColor.Color.R, 2) +
+ Math.Pow(color.G - namedColor.Color.G, 2) +
+ Math.Pow(color.B - namedColor.Color.B, 2));
+
+ if (distance < shortestDistance) {
+ shortestDistance = distance;
+ closestColor = namedColor;
+ }
+ }
+ return closestColor.Name;
+ }
+ }
+
+ public partial class Gh3539 : ContentPage
+ {
+ public Gh3539()
+ {
+ InitializeComponent();
+ }
+
+ public Gh3539(bool useCompiledXaml)
+ {
+ //this stub will be replaced at compile time
+ }
+
+
+ [TestFixture]
+ class Tests
+ {
+ [SetUp]
+ public void Setup()
+ {
+ Device.PlatformServices = new MockPlatformServices();
+ }
+
+ [TearDown]
+ public void TearDown()
+ {
+ Device.PlatformServices = null;
+ }
+
+ [TestCase(true)]
+ public void CompiledBindingCodeIsValid(bool useCompiledXaml)
+ {
+ var layout = new Gh3539(useCompiledXaml);
+ }
+ }
+ }
+}
diff --git a/Xamarin.Forms.Xaml.UnitTests/Xamarin.Forms.Xaml.UnitTests.csproj b/Xamarin.Forms.Xaml.UnitTests/Xamarin.Forms.Xaml.UnitTests.csproj
index 6f104aa1a..19fa056bd 100644
--- a/Xamarin.Forms.Xaml.UnitTests/Xamarin.Forms.Xaml.UnitTests.csproj
+++ b/Xamarin.Forms.Xaml.UnitTests/Xamarin.Forms.Xaml.UnitTests.csproj
@@ -637,6 +637,9 @@
Gh3512.xaml
+
+ Gh3280.xaml
+
@@ -1159,6 +1162,10 @@
Designer
MSBuild:UpdateDesignTimeXaml
+
+ MSBuild:UpdateDesignTimeXaml
+ Designer
+