}
[Test]
- public void ContentPageWithMissingType()
+ public void ContentPageWithMissingTypeMockviewReplacement()
{
XamlLoader.FallbackTypeResolver = (p, type) => type ?? typeof(MockView);
}
[Test]
+ public void ContentPageWithMissingTypeNoReplacement()
+ {
+ XamlLoader.FallbackTypeResolver = (p, type) => type;
+
+ var xaml = @"
+ <ContentPage xmlns=""http://xamarin.com/schemas/2014/forms""
+ xmlns:local=""clr-namespace:MissingNamespace;assembly=MissingAssembly""
+ xmlns:x=""http://schemas.microsoft.com/winfx/2006/xaml"">
+ <ContentPage.Content>
+ <local:MyCustomButton Foo=""Bar"">
+ <local:MyCustomButton.Qux>
+ <Label />
+ </local:MyCustomButton.Qux>
+ </local:MyCustomButton>
+ </ContentPage.Content>
+ </ContentPage>";
+
+ var page = (ContentPage)XamlLoader.Create(xaml, true);
+ Assert.That(page.Content, Is.Null);
+ }
+
+ [Test]
public void MissingTypeWithKnownProperty()
{
XamlLoader.FallbackTypeResolver = (p, type) => type ?? typeof(Button);
public bool StopOnResourceDictionary { get; }
public bool VisitNodeOnDataTemplate => true;
public bool SkipChildren(INode node, INode parentNode) => false;
- public bool IsResourceDictionary(ElementNode node) => typeof(ResourceDictionary).IsAssignableFrom(Context.Types[node]);
+ public bool IsResourceDictionary(ElementNode node) => Context.Types.TryGetValue(node, out var type) && typeof(ResourceDictionary).IsAssignableFrom(type);
public void Visit(ValueNode node, INode parentNode)
{
var parentElement = parentNode as IElementNode;
var value = Values [node];
- var source = Values [parentNode];
+ if (!Values.TryGetValue(parentNode, out var source) && Context.ExceptionHandler != null)
+ return;
+
XmlName propertyName;
if (TryGetPropertyName(node, parentNode, out propertyName)) {
parentElement = parentNode as IElementNode;
}
- var value = Values[node];
+ if (!Values.TryGetValue(node, out var value) && Context.ExceptionHandler != null)
+ return;
if (propertyName != XmlName.Empty || TryGetPropertyName(node, parentNode, out propertyName)) {
if (Skips.Contains(propertyName))
if (parentElement.SkipProperties.Contains(propertyName))
return;
- var source = Values[parentNode];
+ if (!Values.TryGetValue(parentNode, out var source) && Context.ExceptionHandler != null)
+ return;
ProvideValue(ref value, node, source, propertyName);
SetPropertyValue(source, propertyName, value, Context.RootElement, node, Context, node);
}
else if (IsCollectionItem(node, parentNode) && parentNode is IElementNode) {
- var source = Values[parentNode];
+ if (!Values.TryGetValue(parentNode, out var source) && Context.ExceptionHandler != null)
+ return;
ProvideValue(ref value, node, source, XmlName.Empty);
string contentProperty;
Exception xpe = null;
throw xpe;
}
else if (IsCollectionItem(node, parentNode) && parentNode is ListNode) {
- var source = Values[parentNode.Parent];
+ if (!Values.TryGetValue(parentNode.Parent, out var source) && Context.ExceptionHandler != null)
+ return;
ProvideValue(ref value, node, source, XmlName.Empty);
var parentList = (ListNode)parentNode;
if (Skips.Contains(parentList.XmlName))
{
object value = null;
- XamlParseException xpe;
var type = XamlParser.GetElementType(node.XmlType, node, Context.RootElement?.GetType().GetTypeInfo().Assembly,
- out xpe);
- if (xpe != null)
+ out XamlParseException xpe);
+ if (xpe != null) {
+ if (Context.ExceptionHandler != null) {
+ Context.ExceptionHandler(xpe);
+ return;
+ }
throw xpe;
-
+ }
Context.Types[node] = type;
if (IsXaml2009LanguagePrimitive(node))
value = CreateLanguagePrimitive(type, node);
public void Visit(ValueNode node, INode parentNode)
{
- if (!typeof(ResourceDictionary).IsAssignableFrom(Context.Types[((IElementNode)parentNode)]))
+ if (!Context.Types.TryGetValue((IElementNode)parentNode, out var type) || !typeof(ResourceDictionary).IsAssignableFrom(type))
return;
node.Accept(new ApplyPropertiesVisitor(Context, stopOnResourceDictionary: false), parentNode);
public void Visit(ElementNode node, INode parentNode)
{
- var value = Values[node];
- XmlName propertyName;
+ if (!Values.TryGetValue(node, out var value) && Context.ExceptionHandler != null)
+ return;
+
//Set RD to VE
- if (typeof(ResourceDictionary).IsAssignableFrom(Context.Types[node]) && ApplyPropertiesVisitor.TryGetPropertyName(node, parentNode, out propertyName)) {
+ if (typeof(ResourceDictionary).IsAssignableFrom(Context.Types[node]) && ApplyPropertiesVisitor.TryGetPropertyName(node, parentNode, out XmlName propertyName)) {
if ((propertyName.LocalName == "Resources" ||
propertyName.LocalName.EndsWith(".Resources", StringComparison.Ordinal)) && value is ResourceDictionary) {
var source = Values[parentNode];
//Only proceed further if the node is a keyless RD
if ( parentNode is IElementNode
- && typeof(ResourceDictionary).IsAssignableFrom(Context.Types[((IElementNode)parentNode)])
+ && Context.Types.TryGetValue((IElementNode)parentNode, out var parentType)
+ && typeof(ResourceDictionary).IsAssignableFrom(parentType)
&& !((IElementNode)parentNode).Properties.ContainsKey(XmlName.xKey))
node.Accept(new ApplyPropertiesVisitor(Context, stopOnResourceDictionary: false), parentNode);
else if ( parentNode is ListNode
if (enode is null)
return false;
if ( parentNode is IElementNode
- && typeof(ResourceDictionary).IsAssignableFrom(Context.Types[((IElementNode)parentNode)])
+ && Context.Types.TryGetValue((IElementNode)parentNode, out var parentType)
+ && typeof(ResourceDictionary).IsAssignableFrom(parentType)
&& !((IElementNode)parentNode).Properties.ContainsKey(XmlName.xKey))
return true;
if ( parentNode is ListNode