diff options
author | E.Z. Hart <hartez@users.noreply.github.com> | 2016-04-07 00:12:07 -0600 |
---|---|---|
committer | Jason Smith <jason.smith@xamarin.com> | 2016-04-06 23:12:07 -0700 |
commit | c98d338e15a29897e3a9a9d03d30dd3c70347925 (patch) | |
tree | 151819a41191d12609a5455c48e84be0b3879452 | |
parent | 1363f383b17d68fbafadc773b9f06f477f9744c9 (diff) | |
download | xamarin-forms-c98d338e15a29897e3a9a9d03d30dd3c70347925.tar.gz xamarin-forms-c98d338e15a29897e3a9a9d03d30dd3c70347925.tar.bz2 xamarin-forms-c98d338e15a29897e3a9a9d03d30dd3c70347925.zip |
Force conversion to target type when Static Resource returns OnPlatform<T>
5 files changed, 128 insertions, 4 deletions
diff --git a/Xamarin.Forms.Controls.Issues/Xamarin.Forms.Controls.Issues.Shared/Bugzilla39636.xaml b/Xamarin.Forms.Controls.Issues/Xamarin.Forms.Controls.Issues.Shared/Bugzilla39636.xaml new file mode 100644 index 00000000..1f90ee85 --- /dev/null +++ b/Xamarin.Forms.Controls.Issues/Xamarin.Forms.Controls.Issues.Shared/Bugzilla39636.xaml @@ -0,0 +1,40 @@ +<?xml version="1.0" encoding="utf-8" ?> +<local:TestContentPage xmlns="http://xamarin.com/schemas/2014/forms" + xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml" + xmlns:local="clr-namespace:Xamarin.Forms.Controls" + x:Class="Xamarin.Forms.Controls.Issues.Bugzilla39636"> + + <local:TestContentPage.Resources> + <ResourceDictionary> + + <OnPlatform + x:Key="SizeMedium" + x:TypeArguments="x:Double" + iOS="40" + Android="30" + WinPhone="60" /> + + <x:Double x:Key="SizeLarge">80</x:Double> + + </ResourceDictionary> + </local:TestContentPage.Resources> + + <local:TestContentPage.Content> + <StackLayout HorizontalOptions="Fill" VerticalOptions="Fill"> + <Label Text="Success"></Label> + <Label Text="If there is a blue box and a red box below, this test has passed. If the application crashes, the test has not passed."></Label> + <BoxView HorizontalOptions="Center" VerticalOptions="Center" BackgroundColor="Blue" WidthRequest="{StaticResource SizeMedium}"> + <BoxView.HeightRequest> + <OnPlatform + x:TypeArguments="x:Double" + iOS="40" + Android="30" + WinPhone="60" /> + </BoxView.HeightRequest> + </BoxView> + <BoxView HorizontalOptions="Center" VerticalOptions="Center" BackgroundColor="Red" WidthRequest="{StaticResource SizeLarge}"> + + </BoxView> + </StackLayout> + </local:TestContentPage.Content> +</local:TestContentPage>
\ No newline at end of file diff --git a/Xamarin.Forms.Controls.Issues/Xamarin.Forms.Controls.Issues.Shared/Bugzilla39636.xaml.cs b/Xamarin.Forms.Controls.Issues/Xamarin.Forms.Controls.Issues.Shared/Bugzilla39636.xaml.cs new file mode 100644 index 00000000..45e2c8c8 --- /dev/null +++ b/Xamarin.Forms.Controls.Issues/Xamarin.Forms.Controls.Issues.Shared/Bugzilla39636.xaml.cs @@ -0,0 +1,47 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +using Xamarin.Forms; +using Xamarin.Forms.CustomAttributes; +using Xamarin.Forms.Xaml; + +#if UITEST +using Xamarin.Forms.Core.UITests; +using Xamarin.UITest; +using NUnit.Framework; +#endif + + +namespace Xamarin.Forms.Controls.Issues +{ + [Preserve(AllMembers = true)] + [Issue(IssueTracker.Bugzilla, 39636, "Cannot use XamlC with OnPlatform in resources, it throws System.InvalidCastException", PlatformAffected.All)] + #if APP + [XamlCompilation(XamlCompilationOptions.Compile)] + #endif + public partial class Bugzilla39636 : TestContentPage + { + public Bugzilla39636 () + { +#if APP + InitializeComponent (); +#endif + } + + protected override void Init() + { + + } + +#if UITEST + [Test] + public void DoesNotCrash() + { + RunningApp.WaitForElement(q => q.Text("Success")); + } +#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 93de60b1..3d745c38 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 @@ -90,6 +90,10 @@ <DependentUpon>Bugzilla39463.xaml</DependentUpon> <SubType>Code</SubType> </Compile> + <Compile Include="$(MSBuildThisFileDirectory)Bugzilla39636.xaml.cs"> + <DependentUpon>Bugzilla39636.xaml</DependentUpon> + <SubType>Code</SubType> + </Compile> <Compile Include="$(MSBuildThisFileDirectory)Bugzilla39702.cs" /> <Compile Include="$(MSBuildThisFileDirectory)CarouselAsync.cs" /> <Compile Include="$(MSBuildThisFileDirectory)Bugzilla34561.cs" /> @@ -507,4 +511,10 @@ <Generator>MSBuild:UpdateDesignTimeXaml</Generator> </EmbeddedResource> </ItemGroup> + <ItemGroup> + <EmbeddedResource Include="$(MSBuildThisFileDirectory)Bugzilla39636.xaml"> + <SubType>Designer</SubType> + <Generator>MSBuild:UpdateDesignTimeXaml</Generator> + </EmbeddedResource> + </ItemGroup> </Project>
\ No newline at end of file diff --git a/Xamarin.Forms.Core.Android.UITests/Xamarin.Forms.Core.Android.UITests.csproj b/Xamarin.Forms.Core.Android.UITests/Xamarin.Forms.Core.Android.UITests.csproj index f17218c6..7562fc25 100644 --- a/Xamarin.Forms.Core.Android.UITests/Xamarin.Forms.Core.Android.UITests.csproj +++ b/Xamarin.Forms.Core.Android.UITests/Xamarin.Forms.Core.Android.UITests.csproj @@ -270,7 +270,7 @@ <Compile Include="PlatformTests\DisplayAlertUITestsAndroid.cs" /> <Compile Include="..\Xamarin.Forms.Core.iOS.UITests\Tests\AppearingUITests.cs"> <Link>Tests\AppearingUITests.cs</Link> - </Compile> + </Compile> <Compile Include="..\Xamarin.Forms.Core.iOS.UITests\Tests\AutomationIDUITests.cs"> <Link>Tests\AutomationIDUITests.cs</Link> </Compile> @@ -295,6 +295,10 @@ <Project>{67f9d3a8-f71e-4428-913f-c37ae82cdb24}</Project> <Name>Xamarin.Forms.Platform</Name> </ProjectReference> + <ProjectReference Include="..\Xamarin.Forms.Xaml\Xamarin.Forms.Xaml.csproj"> + <Project>{9DB2F292-8034-4E06-89AD-98BBDA4306B9}</Project> + <Name>Xamarin.Forms.Xaml</Name> + </ProjectReference> </ItemGroup> <ItemGroup> <Service Include="{82A7F48D-3B50-4B1E-B82E-3ADA8210C358}" /> diff --git a/Xamarin.Forms.Xaml/MarkupExtensions/StaticResourceExtension.cs b/Xamarin.Forms.Xaml/MarkupExtensions/StaticResourceExtension.cs index e5a7aef7..4f1465d3 100644 --- a/Xamarin.Forms.Xaml/MarkupExtensions/StaticResourceExtension.cs +++ b/Xamarin.Forms.Xaml/MarkupExtensions/StaticResourceExtension.cs @@ -1,4 +1,5 @@ using System; +using System.Reflection; namespace Xamarin.Forms.Xaml { @@ -32,13 +33,35 @@ namespace Xamarin.Forms.Xaml continue; object res; if (ve.Resources.TryGetValue(Key, out res)) - return res; + { + return ConvertCompiledOnPlatform(res); + } } if (Application.Current != null && Application.Current.Resources != null && Application.Current.Resources.ContainsKey(Key)) - return Application.Current.Resources[Key]; + { + var resource = Application.Current.Resources[Key]; + + return ConvertCompiledOnPlatform(resource); + } + + throw new XamlParseException($"StaticResource not found for key {Key}", xmlLineInfo); + } + + static object ConvertCompiledOnPlatform(object resource) + { + var actualType = resource.GetType(); + if (actualType.GetTypeInfo().IsGenericType && actualType.GetGenericTypeDefinition() == typeof(OnPlatform<>)) + { + // If we're accessing OnPlatform via a StaticResource in compiled XAML + // we'll have to handle the cast to the target type manually + // (Normally the compiled XAML handles this by calling `implicit` explicitly, + // but it doesn't know to do that when it's using a static resource) + var method = actualType.GetRuntimeMethod("op_Implicit", new[] { actualType }); + resource = method.Invoke(resource, new[] { resource }); + } - throw new XamlParseException(string.Format("StaticResource not found for key {0}", Key), xmlLineInfo); + return resource; } } }
\ No newline at end of file |