Carl
Carl

Reputation: 861

Xaml markup extension not found

In my Xamarin Forms app I am trying to set the source of an Embedded Image in one of my xaml files but when creating the custom namespace I get the error Xamarin.Forms.Xaml.XamlParseException: Position 31:12. MarkupExtension not found for local:ImageResource. I am basing it on the official documentation at https://developer.xamarin.com/guides/xamarin-forms/working-with/images/#Embedded_Images and have also checked out the sample code. My assembly name and default namespace both match that in the xaml file.

I am using Visual Studio 2015 on Windows. I have had someone else to try the code on Xamarin Studio on a Mac and the code works fine and the image displays.

xaml file

<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
         xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
         xmlns:local="clr-namespace:App;assembly=App"
         x:Class="App.LoginPage">

 <RelativeLayout>

    <Label Text="Logo"
       RelativeLayout.WidthConstraint="{ConstraintExpression Type=RelativeToParent, Property=Width, Factor=1}"
       RelativeLayout.HeightConstraint="{ConstraintExpression Type=RelativeToParent, Property=Height, Factor=0.3}" BackgroundColor="Aqua" />

    <StackLayout Spacing="20" Padding="20"
       VerticalOptions="Center"
       RelativeLayout.WidthConstraint="{ConstraintExpression Type=RelativeToParent, Property=Width, Factor=1}"
       RelativeLayout.HeightConstraint="{ConstraintExpression Type=RelativeToParent, Property=Height, Factor=0.5}"
       RelativeLayout.XConstraint= "{ConstraintExpression Type=RelativeToParent, Property=Width, Factor=0}"
       RelativeLayout.YConstraint= "{ConstraintExpression Type=RelativeToParent, Property=Height, Factor=0.3}">

      <Entry Placeholder="Username"
         Text="{Binding Username}"/>
      <Entry Placeholder="Password"
         Text="{Binding Password}"
         IsPassword="true"/>
      <Button Text="Login" TextColor="White"
          BackgroundColor="Blue"
          Command="{Binding LoginCommand}"/>

    </StackLayout>

    <Image Source="{local:ImageResource App.logo.png}"
       Aspect="AspectFill"
       RelativeLayout.WidthConstraint="{ConstraintExpression Type=RelativeToParent, Property=Width, Factor=0.4}"
       RelativeLayout.HeightConstraint="{ConstraintExpression Type=RelativeToParent, Property=Height, Factor=0.15}"
       RelativeLayout.XConstraint= "{ConstraintExpression Type=RelativeToParent, Property=Width, Factor=0.6}"
       RelativeLayout.YConstraint= "{ConstraintExpression Type=RelativeToParent, Property=Height, Factor=0.85}" />

 </RelativeLayout>

</ContentPage>

Can anyone help?

Upvotes: 6

Views: 8519

Answers (4)

Masciuniria
Masciuniria

Reputation: 172

just add [ContentProperty("Source")] before your Markup class. like:

[ContentProperty("Source")] public class EmbeddedImage : IMarkupExtension { //................ }

Upvotes: -1

Keith Rome
Keith Rome

Reputation: 3228

Dakshal's answer should be correct however one thing that might be missing is that the markup extension needs to reside in the same namespace/assembly that you are pointing to in your xmlns alias. So be sure that this code exists in your forms project:

namespace App
{
    [ContentProperty ("Source")]
    public class ImageResourceExtension : IMarkupExtension
    {
        public string Source { get; set; }

        public object ProvideValue (IServiceProvider serviceProvider)
        {
            if (Source == null)
                return null;

            // Do your translation lookup here, using whatever method you require
            var imageSource = ImageSource.FromResource(Source);

            return imageSource;
        }
    }
}

It is important that the namespace (App in this example) matches your alias designated in the XAML file (xmlns:local="clr-namespace:App;assembly=App" in this case).

The documentation does not point this out. It assumes that you know to correlate the namespace alias with the CLR namespace that you place the extension code in.

Upvotes: 6

Dakshal Raijada
Dakshal Raijada

Reputation: 1261

Because there is no built-in type converter from string to ResourceImageSource, these types of images cannot be natively loaded by Xaml.

To get around this restriction, a simple custom Xaml markup extension can be written to load images using a Resource ID specified in Xaml.

[ContentProperty ("Source")]
public class ImageResourceExtension : IMarkupExtension
 { 
  public string Source { get; set; }

  public object ProvideValue (IServiceProvider serviceProvider)
 {
   if (Source == null)
   return null;

  // Do your translation lookup here, using whatever method you require
  var imageSource = ImageSource.FromResource(Source);

  return imageSource;
 }
}

To use this extension add a custom xmlns to the Xaml, using the correct namespace and assembly values for the project. The image source can then be set using this syntax: {local:ImageResource WorkingWithImages.beach.jpg}

Source

Upvotes: 6

JKennedy
JKennedy

Reputation: 18799

why dont you just do:

<Image Source="logo.png"/>

This will look for the image in the following directories:

Android: Resources\drawable

iOS: Resources

UWP: basefolder

See more here (Working with images in Xamarin)

Upvotes: 0

Related Questions