if (CanAdd(parent, localName, valueNode, context))
return Add(parent, localName, valueNode, iXmlLineInfo, context);
- throw new XamlParseException($"No property, bindable property, or event found for '{localName}'", iXmlLineInfo);
+ throw new XamlParseException($"No property, bindable property, or event found for '{localName}', or mismatching type between value and property.", iXmlLineInfo);
}
static FieldReference GetBindablePropertyReference(VariableDefinition parent, string namespaceURI, ref string localName, out bool attached, ILContext context, IXmlLineInfo iXmlLineInfo)
VariableDefinition varValue;
if (!context.Variables.TryGetValue(valueNode as IElementNode, out varValue))
return false;
+ var implicitOperator = varValue.VariableType.GetImplicitOperatorTo(module.Import(typeof(BindingBase)), module);
+ if (implicitOperator != null)
+ return true;
+
return varValue.VariableType.InheritsFromOrImplements(module.Import(typeof(BindingBase)));
}
{
var module = context.Body.Method.Module;
var varValue = context.Variables [elementNode];
+ var implicitOperator = varValue.VariableType.GetImplicitOperatorTo(module.Import(typeof(BindingBase)), module);
//TODO: check if parent is a BP
var setBinding = typeof(BindableObject).GetMethod("SetBinding", new [] { typeof(BindableProperty), typeof(BindingBase) });
yield return Instruction.Create(OpCodes.Ldloc, parent);
yield return Instruction.Create(OpCodes.Ldsfld, bpRef);
yield return Instruction.Create(OpCodes.Ldloc, varValue);
+ if (implicitOperator != null)
+// IL_000f: call !0 class [Xamarin.Forms.Core]Xamarin.Forms.OnPlatform`1<BindingBase>::op_Implicit(class [Xamarin.Forms.Core]Xamarin.Forms.OnPlatform`1<!0>)
+ yield return Instruction.Create(OpCodes.Call, module.Import(implicitOperator));
yield return Instruction.Create(OpCodes.Callvirt, module.Import(setBinding));
}
--- /dev/null
+using NUnit.Framework;
+using Xamarin.Forms.Core.UnitTests;
+
+namespace Xamarin.Forms.Xaml.UnitTests
+{
+ public partial class Bz44213 : ContentPage
+ {
+ public Bz44213()
+ {
+ InitializeComponent();
+ }
+
+ public Bz44213(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)]
+ [TestCase(false)]
+ public void BindingInOnPlatform(bool useCompiledXaml)
+ {
+ ((MockPlatformServices)Device.PlatformServices).RuntimePlatform = Device.iOS;
+ var p = new Bz44213(useCompiledXaml);
+ p.BindingContext = new { Foo = "Foo", Bar = "Bar" };
+ Assert.AreEqual("Foo", p.label.Text);
+ ((MockPlatformServices)Device.PlatformServices).RuntimePlatform = Device.Android;
+ p = new Bz44213(useCompiledXaml);
+ p.BindingContext = new { Foo = "Foo", Bar = "Bar" };
+ Assert.AreEqual("Bar", p.label.Text);
+ }
+ }
+ }
+}
\ No newline at end of file
<Compile Include="Issues\Bz43733.xaml.cs">
<DependentUpon>Bz43733.xaml</DependentUpon>
</Compile>
+ <Compile Include="Issues\Bz44213.xaml.cs">
+ <DependentUpon>Bz44213.xaml</DependentUpon>
+ </Compile>
</ItemGroup>
<Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
<Import Project="..\.nuspec\Xamarin.Forms.Debug.targets" />
<EmbeddedResource Include="Issues\Bz43733.xaml">
<Generator>MSBuild:UpdateDesignTimeXaml</Generator>
</EmbeddedResource>
+ <EmbeddedResource Include="Issues\Bz44213.xaml">
+ <Generator>MSBuild:UpdateDesignTimeXaml</Generator>
+ </EmbeddedResource>
</ItemGroup>
<ItemGroup>
<Service Include="{82A7F48D-3B50-4B1E-B82E-3ADA8210C358}" />