【问题标题】:Xaml markup extension not found未找到 Xaml 标记扩展
【发布时间】:2016-08-13 07:18:56
【问题描述】:

在我的 Xamarin Forms 应用程序中,我试图在我的一个 xaml 文件中设置嵌入式图像的源,但是在创建自定义命名空间时出现错误 Xamarin.Forms.Xaml.XamlParseException: Position 31:12. MarkupExtension not found for local:ImageResource。我基于https://developer.xamarin.com/guides/xamarin-forms/working-with/images/#Embedded_Images 的官方文档,并且还检查了示例代码。我的程序集名称和默认命名空间都与 xaml 文件中的名称匹配。

我在 Windows 上使用 Visual Studio 2015。我让其他人在 Mac 上的 Xamarin Studio 上尝试了代码,代码运行良好并且图像显示。

xaml 文件

<?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>

谁能帮忙?

【问题讨论】:

  • 您在构建或运行项目时是否收到此错误?

标签: xamarin.forms


【解决方案1】:

由于没有内置的从字符串到 ResourceImageSource 的类型转换器,这些类型的图像不能被 Xaml 原生加载。

要绕过这个限制,可以编写一个简单的自定义 Xaml 标记扩展来使用 Xaml 中指定的资源 ID 加载图像。

[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;
 }
}

要使用此扩展,请使用项目的正确命名空间和程序集值,将自定义 xmlns 添加到 Xaml。然后可以使用以下语法设置图像源:{local:ImageResource WorkingWithImages.beach.jpg}

Source

【讨论】:

  • 谢谢,我现在看到了问题。
【解决方案2】:

Dakshal 的回答应该是正确的,但是可能缺少的一件事是标记扩展需要驻留在您在 xmlns 别名中指向的同一个命名空间/程序集中。因此,请确保此代码存在于您的表单项目中:

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;
        }
    }
}

命名空间(本例中为App)与您在 XAML 文件中指定的别名(本例中为xmlns:local="clr-namespace:App;assembly=App")相匹配非常重要。

文档没有指出这一点。它假定您知道将命名空间别名与放置扩展代码的 CLR 命名空间相关联。

【讨论】:

    【解决方案3】:

    你为什么不这样做:

    <Image Source="logo.png"/>
    

    这将在以下目录中查找图像:

    Android:资源\drawable

    iOS:资源

    UWP:基本文件夹

    查看更多here (Working with images in Xamarin)

    【讨论】:

    • 这需要在每个项目中拥有每个图像的副本。嵌入图像允许您仅在 PCL 中拥有图像的一次副本
    • @Jason 您认为在 PCL 项目中拥有单一副本的优势是什么?我可以看到将它们保留在本机项目中的优势(主要是您可以使用每个平台的自动调整大小机制)。当您构建应用程序时,您只构建了一个特定的平台,您实际上不会获得每个图像的 2、3、5 个副本,而只是您实际需要和使用的那些。那么将它们嵌入 PCL 有什么好处呢?
    • 易于维护。如果您有 30 张图片,并且您的客户为您提供了更新的艺术品以供使用,您是需要更新 1 个项目还是 3 个?
    【解决方案4】:

    只需在您的标记类之前添加[ContentProperty("Source")]。喜欢:

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2012-02-01
      • 2011-03-11
      • 1970-01-01
      • 2011-12-07
      • 2011-03-10
      • 2018-03-02
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多