如何在 Xamarin.Forms UWP 中使用图像?

How to use Images in Xamarin.Forms UWP?

我目前正在 Xamarin.Forms UWP 中创建示例系统。我想知道为什么我调用图像的代码在 Android 中工作时在 UWP 部分似乎无法正常工作。我还想将图像设置为背景和图像作为按钮。

如何编写代码才能使其在两个平台上正常运行?

这是我使用的代码:

<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
         xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
         x:Class="XamarinFormsDemo.Views.LoginPage"
         BackgroundImage="bg3.jpg"
         Title="MainPage">
  <Label Text="{Binding MainText}" VerticalOptions="Center" HorizontalOptions="Center" />

  <StackLayout VerticalOptions="Center"
             Padding="40">
    <Image Source="ebmslogo1.png"/>

    <StackLayout Padding="0,50,0,0">

      <Entry x:Name="txtUserName"
             Placeholder="Username"
             x:Hint="Username"
             BackgroundColor="Black"
             TextColor="White"/>

  <Entry x:Name="txtPassword"
         Placeholder="Password"
         IsPassword="true"
         BackgroundColor="Black"
         TextColor="White"/>

      <Button Text="LOG IN"
          FontSize="14"
         BackgroundColor="Teal"
         Clicked="NavigateButton_OnClicked"/>

    </StackLayout>

  </StackLayout>

</ContentPage>

我的图片位于 .Droid > Resources > drawable

对于 UWP 中的 Xamarin Forms,图像必须位于根项目目录(而不是资产)中,并且构建操作设置为 Content。

图像将像在 Xamarin Forms 中的 Android 和 iOS 中一样工作。

在 UWP 中你可以使用

img.Source = new BitmapImage(new Uri("ms-appx:///Assets/Logo.png"));

图像位于 Assets 文件夹中,如下图所示

对于 UWP Xamarin 表单:

  1. 在根目录中创建名为 "scale-100" 的文件夹,然后将所有图像放入其中。
  2. 指定扩展名为 ex 的图像名称:<Image Source="myimage.png"/>

您还可以根据此 Link

的指定创建 "scale-xxx"

在 UWP 项目中创建一个名为 Resources 的文件夹,将图像和 Content 作为构建操作放在那里

然后使用这个 MarkupExtension

using System;
using Xamarin.Forms;
using Xamarin.Forms.Xaml;

namespace XamarinFormsMoshCourse.MarkupExtensions
{
    [ContentProperty(nameof(Source))]
    public class PlatformResourceImageExtension : IMarkupExtension
    {
        public string Source { get; set; }

        public object ProvideValue(IServiceProvider serviceProvider)
        {
            if (String.IsNullOrWhiteSpace(Source)) return null;

            string imageSource = String.Empty;

            switch (Device.RuntimePlatform)
            {
                case Device.iOS:
                    {
                        imageSource = Source;
                        break;
                    }
                case Device.Android:
                    {
                        imageSource = Source;
                        break;
                    }
                case Device.UWP:
                    {
                        imageSource = String.Concat("Resources/", Source);
                        break;
                    }
            }
            return ImageSource.FromFile(imageSource);
        }
    }
}

添加标记扩展 foler 作为 xaml 命名空间并像这样使用

     <Button ImageSource="{local:PlatformResourceImage clock.png}"/>
        <Image Source="{local:PlatformResourceImage clock.png}"/>

现在您可以在所有平台上对相同的图像路径使用相同的语法

您可以创建一个文件夹并使用 Custom Renderer 更改路径,如下所示:

[assembly: ExportRenderer(typeof(Image), typeof(CustomImageRenderer))]

public class CustomImageRenderer : ImageRenderer
{
    protected override void OnElementChanged(ElementChangedEventArgs<Image> e)
    {
        if(e.NewElement != null)
        {
            var source = e.NewElement.Source;
            if(source is FileImageSource fileImageSource)
            {
                fileImageSource.File = $"Assets/{fileImageSource.File}";
            }
        }      
        base.OnElementChanged(e);
    }
}

显然您需要在 uwp 和 android 中使用图像,所以这是我的解决方案:

  1. 在 xaml
  2. 中声明图像
<Image x:Name="kitty"/>
  1. 在 pcl 项目中添加一个 "Resources" 文件夹
  2. 在 "Resources"
  3. 中添加一个 "Images" 文件夹
  4. 粘贴图片并转到图片 属性(右击>属性)
  5. 将 "build Action" 更改为“嵌入资源 (microsoft documentation)
  6. 将此添加到您的页面代码中:
kitty.Source = ImageSource.FromResource("Whosebug.Resources.Images.kitty.png", typeof(MainPage).Assembly);

优势:

  • 您可以多次使用同一张图片,而不需要在每个项目中都使用一个副本

缺点:

  • 不知道能不能在MVVM项目中使用

如果您只想使用您的 uwp 项目而不是其他项目,只需将文件夹添加到 "Assets" 并让您 xaml 像这样

<Image x:Name="kitty" Source="Assets/Images/kitty.png"/>