簡體   English   中英

如何在 Xamarin.Forms 中制作可綁定的標記擴展

[英]How to make a bindable markup extension in Xamarin.Forms

眾所周知,沒有內置的類型轉換器 class 可以將字符串轉換為 ImageSource object。

當我想讓我的模型有一個字符串屬性表示嵌入圖像的 ResouceID,然后 XAML 的 Image.Source 屬性通過數據綁定綁定到該屬性時,這給我帶來了挑戰。

最簡單的解決方案是在 model 中添加另一個 ImageSource 類型的屬性,該屬性僅獲取基於字符串 ResourceID 屬性生成的圖像源 object,然后將其綁定到 Image.Source。

It works well but the problem is I had to add Xamarin.Forms dependency to the project defining the model which was .NET Stardard class library.

我按項目拆分視圖和模型/視圖模型,以便 model 可以在其他應用程序中重復使用。 因此,model 被設計為只有基本類型,如 int、string 等。 The easiest solution have made the model class dependent on Xamarin.Forms and I worry if it may bring about some issues later when I use for other frameworks.

為了制定解決方案,我嘗試通過參考MS文檔在共享項目中聲明具有綁定能力的標記擴展class,但不起作用。

擴展 class 代碼如下。


// This class is added to the shared project, where a page class exsists.
public class BindableImageSourceExtension : BindableObject, IMarkupExtension
{
    // This is a unique property of BindableImageSource element
    public string ResourceID
    {
        get { return (string)GetValue(ResouceIDProperty); }
        set { SetValue(ResouceIDProperty, value); }
    }

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

        // Images are embeded to a project named BusinessSession that holds Data class.
        return ImageSource.FromResource(ResourceID, typeof(BusinessSession).GetTypeInfo().Assembly); 
    }

    public static readonly BindableProperty ResouceIDProperty =
            BindableProperty.Create("ResourceID", typeof(string),
                                    typeof(BindableImageSourceExtension),
                                    default(string));
}

任何人都可以幫助解決這個問題?

無需創建bindableproperty ,解決方案在文檔中列出:

因為沒有內置的從字符串到 ResourceImageSource 的類型轉換器,所以 XAML 無法原生加載這些類型的圖像。 相反,可以編寫一個簡單的自定義 XAML 標記擴展來使用 XAML 中指定的資源 ID 加載圖像:

[ContentProperty (nameof(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, typeof(ImageResourceExtension).GetTypeInfo().Assembly);

   return imageSource;
 }
}

在 Xaml 中:

 <StackLayout VerticalOptions="Center" HorizontalOptions="Center">
   <!-- use a custom Markup Extension -->
   <Image Source="{local:ImageResource WorkingWithImages.beach.jpg}" />
 </StackLayout>

您還可以創建自己的ValueConverter

public class stringToImageSourceConverter : IValueConverter
{
    public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
    {
        return ImageSource.FromResource(value as string, typeof(MainPage).GetTypeInfo().Assembly);
    }

    public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
    {
        return value;
    }
}

在 Xaml 中:

<Image Source="{Binding Path, Converter={StaticResource stringToImage}}" VerticalOptions="CenterAndExpand" HorizontalOptions="CenterAndExpand" />

在這里上傳了一個示例項目。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM