繁体   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