[X] internal CreateFromXaml () (#77)
This commit is contained in:
Родитель
f975a6f2e3
Коммит
c92297047c
|
@ -5,7 +5,7 @@ namespace Xamarin.Forms.Build.Tasks
|
|||
{
|
||||
class ILRootNode : RootNode
|
||||
{
|
||||
public ILRootNode(XmlType xmlType, TypeReference typeReference) : base(xmlType)
|
||||
public ILRootNode(XmlType xmlType, TypeReference typeReference) : base(xmlType, null)
|
||||
{
|
||||
TypeReference = typeReference;
|
||||
}
|
||||
|
|
|
@ -123,7 +123,7 @@ namespace Xamarin.Forms.Xaml.UnitTests
|
|||
var bindable = new Bindable ();
|
||||
|
||||
Assert.IsNull (bindable.Baz);
|
||||
var rootNode = new XamlLoader.RuntimeRootNode (new XmlType("clr-namespace:Xamarin.Forms.Xaml.UnitTests;assembly=Xamarin.Forms.Xaml.UnitTests","Bindable",null), bindable) {
|
||||
var rootNode = new XamlLoader.RuntimeRootNode (new XmlType("clr-namespace:Xamarin.Forms.Xaml.UnitTests;assembly=Xamarin.Forms.Xaml.UnitTests","Bindable",null), bindable, null) {
|
||||
Properties = {
|
||||
{ new XmlName (null, "Baz"), node },
|
||||
}
|
||||
|
@ -142,7 +142,7 @@ namespace Xamarin.Forms.Xaml.UnitTests
|
|||
var bindable = new Bindable ();
|
||||
|
||||
Assert.IsNull (bindable.Baz);
|
||||
var rootNode = new XamlLoader.RuntimeRootNode (new XmlType("clr-namespace:Xamarin.Forms.Xaml.UnitTests;assembly=Xamarin.Forms.Xaml.UnitTests","Bindable",null), bindable) {
|
||||
var rootNode = new XamlLoader.RuntimeRootNode (new XmlType("clr-namespace:Xamarin.Forms.Xaml.UnitTests;assembly=Xamarin.Forms.Xaml.UnitTests","Bindable",null), bindable, null) {
|
||||
Properties = {
|
||||
{ new XmlName (null, "Baz"), node },
|
||||
}
|
||||
|
@ -159,7 +159,7 @@ namespace Xamarin.Forms.Xaml.UnitTests
|
|||
var bindable = new Bindable ();
|
||||
|
||||
Assert.IsNull (bindable.Foo);
|
||||
var rootNode = new XamlLoader.RuntimeRootNode (new XmlType("clr-namespace:Xamarin.Forms.Xaml.UnitTests;assembly=Xamarin.Forms.Xaml.UnitTests","Bindable",null), bindable) {
|
||||
var rootNode = new XamlLoader.RuntimeRootNode (new XmlType("clr-namespace:Xamarin.Forms.Xaml.UnitTests;assembly=Xamarin.Forms.Xaml.UnitTests","Bindable",null), bindable, null) {
|
||||
Properties = {
|
||||
{ new XmlName (null, "Foo"), node },
|
||||
}
|
||||
|
@ -180,7 +180,7 @@ namespace Xamarin.Forms.Xaml.UnitTests
|
|||
var bindable = new Bindable ();
|
||||
|
||||
Assert.IsNull (bindable.Bar);
|
||||
var rootNode = new XamlLoader.RuntimeRootNode (new XmlType("clr-namespace:Xamarin.Forms.Xaml.UnitTests;assembly=Xamarin.Forms.Xaml.UnitTests","Bindable",null), bindable) {
|
||||
var rootNode = new XamlLoader.RuntimeRootNode (new XmlType("clr-namespace:Xamarin.Forms.Xaml.UnitTests;assembly=Xamarin.Forms.Xaml.UnitTests","Bindable",null), bindable, null) {
|
||||
Properties = {
|
||||
{ new XmlName (null, "Bar"), node },
|
||||
}
|
||||
|
@ -200,7 +200,7 @@ namespace Xamarin.Forms.Xaml.UnitTests
|
|||
var bindable = new Bindable ();
|
||||
|
||||
Assert.IsNull (Bindable.GetQux (bindable));
|
||||
var rootNode = new XamlLoader.RuntimeRootNode (new XmlType("clr-namespace:Xamarin.Forms.Xaml.UnitTests;assembly=Xamarin.Forms.Xaml.UnitTests","Bindable",null), bindable) {
|
||||
var rootNode = new XamlLoader.RuntimeRootNode (new XmlType("clr-namespace:Xamarin.Forms.Xaml.UnitTests;assembly=Xamarin.Forms.Xaml.UnitTests","Bindable",null), bindable, null) {
|
||||
Properties = {
|
||||
{ new XmlName ("clr-namespace:Xamarin.Forms.Xaml.UnitTests;assembly=Xamarin.Forms.Xaml.UnitTests", "Bindable.Qux"), node },
|
||||
}
|
||||
|
@ -220,7 +220,7 @@ namespace Xamarin.Forms.Xaml.UnitTests
|
|||
var bindable = new Bindable ();
|
||||
|
||||
Assert.IsNull (bindable.FooBar);
|
||||
var rootNode = new XamlLoader.RuntimeRootNode (new XmlType("clr-namespace:Xamarin.Forms.Xaml.UnitTests;assembly=Xamarin.Forms.Xaml.UnitTests","Bindable",null), bindable) {
|
||||
var rootNode = new XamlLoader.RuntimeRootNode (new XmlType("clr-namespace:Xamarin.Forms.Xaml.UnitTests;assembly=Xamarin.Forms.Xaml.UnitTests","Bindable",null), bindable, null) {
|
||||
Properties = {
|
||||
{ new XmlName (null, "FooBar"), node },
|
||||
}
|
||||
|
|
|
@ -334,6 +334,7 @@
|
|||
<Compile Include="McIgnorable.xaml.cs">
|
||||
<DependentUpon>McIgnorable.xaml</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Include="XamlLoaderCreateTests.cs" />
|
||||
</ItemGroup>
|
||||
<Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
|
||||
<Import Project="..\.nuspec\Xamarin.Forms.Debug.targets" />
|
||||
|
|
|
@ -0,0 +1,38 @@
|
|||
using System;
|
||||
using NUnit.Framework;
|
||||
|
||||
namespace Xamarin.Forms.Xaml.UnitTests
|
||||
{
|
||||
[TestFixture]
|
||||
public class XamlLoaderCreateTests
|
||||
{
|
||||
[Test]
|
||||
public void CreateFromXaml ()
|
||||
{
|
||||
var xaml = @"
|
||||
<ContentView xmlns=""http://xamarin.com/schemas/2014/forms""
|
||||
xmlns:x=""http://schemas.microsoft.com/winfx/2009/xaml""
|
||||
x:Class=""Xamarin.Forms.Xaml.UnitTests.FOO"">
|
||||
<Label Text=""Foo"" x:Name=""label""/>
|
||||
</ContentView>";
|
||||
|
||||
var view = XamlLoader.Create (xaml);
|
||||
Assert.That (view, Is.TypeOf<ContentView> ());
|
||||
Assert.AreEqual ("Foo", ((Label)((ContentView)view).Content).Text);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void CreateFromXamlDoesntFailOnMissingEventHandler ()
|
||||
{
|
||||
var xaml = @"
|
||||
<Button xmlns=""http://xamarin.com/schemas/2014/forms""
|
||||
xmlns:x=""http://schemas.microsoft.com/winfx/2009/xaml""
|
||||
Clicked=""handleClick"">
|
||||
</Button>";
|
||||
|
||||
Button button = null;
|
||||
Assert.DoesNotThrow (() => button = XamlLoader.Create (xaml, true) as Button);
|
||||
Assert.NotNull (button);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -307,19 +307,25 @@ namespace Xamarin.Forms.Xaml
|
|||
if (eventInfo != null && value is string)
|
||||
{
|
||||
var methodInfo = rootElement.GetType().GetRuntimeMethods().FirstOrDefault(mi => mi.Name == (string)value);
|
||||
if (methodInfo == null)
|
||||
{
|
||||
throw new XamlParseException(string.Format("No method {0} found on type {1}", value, rootElement.GetType()),
|
||||
lineInfo);
|
||||
if (methodInfo == null) {
|
||||
var xpe = new XamlParseException (string.Format ("No method {0} found on type {1}", value, rootElement.GetType ()), lineInfo);
|
||||
if (context.DoNotThrowOnExceptions) {
|
||||
System.Diagnostics.Debug.WriteLine (xpe.Message);
|
||||
return;
|
||||
} else
|
||||
throw xpe;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
eventInfo.AddEventHandler(xamlelement, methodInfo.CreateDelegate(eventInfo.EventHandlerType, rootElement));
|
||||
}
|
||||
catch (ArgumentException)
|
||||
{
|
||||
throw new XamlParseException(string.Format("Method {0} does not have the correct signature", value), lineInfo);
|
||||
var xpe = new XamlParseException (string.Format ("Method {0} does not have the correct signature", value), lineInfo);
|
||||
if (context.DoNotThrowOnExceptions)
|
||||
System.Diagnostics.Debug.WriteLine (xpe.Message);
|
||||
else
|
||||
throw xpe;
|
||||
}
|
||||
|
||||
return;
|
||||
|
@ -416,7 +422,10 @@ namespace Xamarin.Forms.Xaml
|
|||
}
|
||||
}
|
||||
|
||||
throw exception;
|
||||
if (context.DoNotThrowOnExceptions)
|
||||
System.Diagnostics.Debug.WriteLine (exception.Message);
|
||||
else
|
||||
throw exception;
|
||||
}
|
||||
|
||||
void SetTemplate(ElementTemplate dt, INode node)
|
||||
|
|
|
@ -66,7 +66,7 @@ namespace Xamarin.Forms.Xaml
|
|||
return;
|
||||
|
||||
XamlParseException xpe;
|
||||
var type = XamlParser.GetElementType(node.XmlType, node, Context.RootElement.GetType().GetTypeInfo().Assembly,
|
||||
var type = XamlParser.GetElementType(node.XmlType, node, Context.RootElement?.GetType().GetTypeInfo().Assembly,
|
||||
out xpe);
|
||||
if (xpe != null)
|
||||
throw xpe;
|
||||
|
|
|
@ -18,5 +18,7 @@ namespace Xamarin.Forms.Xaml
|
|||
public HydratationContext ParentContext { get; set; }
|
||||
|
||||
public BindableObject RootElement { get; set; }
|
||||
|
||||
public bool DoNotThrowOnExceptions { get; set; }
|
||||
}
|
||||
}
|
|
@ -62,25 +62,55 @@ namespace Xamarin.Forms.Xaml
|
|||
continue;
|
||||
}
|
||||
|
||||
var rootnode = new RuntimeRootNode(new XmlType(reader.NamespaceURI, reader.Name, null), view);
|
||||
|
||||
XamlParser.ParseXaml(rootnode, reader);
|
||||
|
||||
var visitorContext = new HydratationContext { RootElement = view };
|
||||
|
||||
rootnode.Accept(new XamlNodeVisitor((node, parent) => node.Parent = parent), null);
|
||||
//set parents for {StaticResource}
|
||||
rootnode.Accept(new ExpandMarkupsVisitor(visitorContext), null);
|
||||
rootnode.Accept(new NamescopingVisitor(visitorContext), null); //set namescopes for {x:Reference}
|
||||
rootnode.Accept(new CreateValuesVisitor(visitorContext), null);
|
||||
rootnode.Accept(new RegisterXNamesVisitor(visitorContext), null);
|
||||
rootnode.Accept(new FillResourceDictionariesVisitor(visitorContext), null);
|
||||
rootnode.Accept(new ApplyPropertiesVisitor(visitorContext, true), null);
|
||||
var rootnode = new RuntimeRootNode (new XmlType (reader.NamespaceURI, reader.Name, null), view, (IXmlNamespaceResolver)reader);
|
||||
XamlParser.ParseXaml (rootnode, reader);
|
||||
Visit (rootnode, new HydratationContext { RootElement = view });
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static object Create (string xaml, bool doNotThrow = false)
|
||||
{
|
||||
object inflatedView = null;
|
||||
using (var reader = XmlReader.Create (new StringReader (xaml))) {
|
||||
while (reader.Read ()) {
|
||||
//Skip until element
|
||||
if (reader.NodeType == XmlNodeType.Whitespace)
|
||||
continue;
|
||||
if (reader.NodeType != XmlNodeType.Element) {
|
||||
Debug.WriteLine ("Unhandled node {0} {1} {2}", reader.NodeType, reader.Name, reader.Value);
|
||||
continue;
|
||||
}
|
||||
|
||||
var rootnode = new RuntimeRootNode (new XmlType (reader.NamespaceURI, reader.Name, null), null, (IXmlNamespaceResolver)reader);
|
||||
XamlParser.ParseXaml (rootnode, reader);
|
||||
var visitorContext = new HydratationContext {
|
||||
DoNotThrowOnExceptions = doNotThrow,
|
||||
};
|
||||
var cvv = new CreateValuesVisitor (visitorContext);
|
||||
cvv.Visit ((ElementNode)rootnode, null);
|
||||
inflatedView = rootnode.Root = visitorContext.Values [rootnode];
|
||||
visitorContext.RootElement = inflatedView as BindableObject;
|
||||
|
||||
Visit (rootnode, visitorContext);
|
||||
break;
|
||||
}
|
||||
}
|
||||
return inflatedView;
|
||||
}
|
||||
|
||||
static void Visit (RootNode rootnode, HydratationContext visitorContext)
|
||||
{
|
||||
rootnode.Accept (new XamlNodeVisitor ((node, parent) => node.Parent = parent), null); //set parents for {StaticResource}
|
||||
rootnode.Accept (new ExpandMarkupsVisitor (visitorContext), null);
|
||||
rootnode.Accept (new NamescopingVisitor (visitorContext), null); //set namescopes for {x:Reference}
|
||||
rootnode.Accept (new CreateValuesVisitor (visitorContext), null);
|
||||
rootnode.Accept (new RegisterXNamesVisitor (visitorContext), null);
|
||||
rootnode.Accept (new FillResourceDictionariesVisitor (visitorContext), null);
|
||||
rootnode.Accept (new ApplyPropertiesVisitor (visitorContext, true), null);
|
||||
}
|
||||
|
||||
static string GetXamlForType(Type type)
|
||||
{
|
||||
var assembly = type.GetTypeInfo().Assembly;
|
||||
|
@ -197,12 +227,12 @@ namespace Xamarin.Forms.Xaml
|
|||
|
||||
public class RuntimeRootNode : RootNode
|
||||
{
|
||||
public RuntimeRootNode(XmlType xmlType, object root) : base(xmlType)
|
||||
public RuntimeRootNode(XmlType xmlType, object root, IXmlNamespaceResolver resolver) : base (xmlType, resolver)
|
||||
{
|
||||
Root = root;
|
||||
}
|
||||
|
||||
public object Root { get; private set; }
|
||||
public object Root { get; internal set; }
|
||||
}
|
||||
}
|
||||
}
|
|
@ -178,7 +178,7 @@ namespace Xamarin.Forms.Xaml
|
|||
|
||||
internal abstract class RootNode : ElementNode
|
||||
{
|
||||
protected RootNode(XmlType xmlType) : base(xmlType, xmlType.NamespaceUri, null)
|
||||
protected RootNode(XmlType xmlType, IXmlNamespaceResolver nsResolver) : base(xmlType, xmlType.NamespaceUri, nsResolver)
|
||||
{
|
||||
}
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче