2016-04-20 80 views
4

在我的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文件中的匹配。未找到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> 

誰能幫助?

+0

當您構建或運行您的項目時是否出現此錯誤? – user1

回答

4

因爲沒有內置類型轉換器從字符串到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。圖像源然後可以使用此語法設置:{本地:ImageResource WorkingWithImages.beach.jpg}

Source

+0

謝謝,我現在看到了這個問題。 – Carl

0

你爲什麼不只是做:

<Image Source="logo.png"/> 

這將尋找在以下目錄中的圖片:

安卓:資源\繪製

的iOS:資源

UWP: basefolder

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

+0

這需要在每個項目中有每個圖像的副本。嵌入式圖像允許您在PCL中只有一次圖像副本 – Jason

+1

@Jason您認爲PCL項目中有單個副本的優點是什麼?我可以看到將他們保留在本地項目中的優勢(主要原因是您可以使用每個平臺的自動調整機制)。當您構建應用程序時,您只會構建特定的平臺,實際上並不會獲得每個圖像的2,3,5個副本,而只是您實際需要和使用的那些。那麼將它們嵌入PCL有什麼優勢? – irreal

+0

易於維護。如果您有30張圖片,並且您的客戶爲您提供了更新的圖稿供您使用,您是否需要更新1個項目或3個? – Jason

1

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名稱空間相關聯。

0

只需在您的標記類之前添加[ContentProperty("Source")]即可。如:

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