Xamarin.Forms Image 电脑版发表于:2022/5/2 20:36 ![](https://img.tnblog.net/arcimg/hb/59e2f99dba0340d09e3ea49cc983167f.png) >#Xamarin.Forms Image [TOC] ## Image标签 tn2>简单来讲就是图片标签,我们有四种创建图片来源的方式:本地图片加载、后台图片定义、加载网络图片和加载嵌入式资源。 首先我们需要两张图片`my1.jpeg`和`my2.png`,在我们创建的Xamarin.Forms中创建一个`images`目录,并将两张图片放到下面的目录中,且将属性改为嵌入式资源。同时,我们可以将该图片放到安卓的`/Resources/drawable/`目录下面。 ![](https://img.tnblog.net/arcimg/hb/2917921b0d4f472d93e89c7919147f19.jpeg) ![](https://img.tnblog.net/arcimg/hb/4c8b24d88b5444aabeec00abd30ff905.png) ![](https://img.tnblog.net/arcimg/hb/970808d812e243d3a65ec633be06a5fc.png) ![](https://img.tnblog.net/arcimg/hb/985c507d068741868dd64a902141c50e.png) tn2>接下来我们创建`Images.xaml`文件来示例各种图片的来源。 ```xml <?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:LableApp" x:Class="LableApp.Images"> <ContentPage.Content> <StackLayout> <!--指定图片--> <Image Source="my1.jpeg" HeightRequest="40" WidthRequest="40"></Image> <!--后台指定图片--> <Image x:Name="imgLogo" HeightRequest="40" WidthRequest="40"></Image> <!--加载网络图片--> <Image Source="https://img.tnblog.net/userdata/heads/dbc68332d521436c983fbc3adc6d9c7f.jpeg" HeightRequest="40" WidthRequest="40" ></Image> <!--加载嵌入式资源--> <Image Source="{local:ImageResource LableApp.Images.my2.png}" HeightRequest="40" WidthRequest="40" ></Image> </StackLayout> </ContentPage.Content> </ContentPage> ``` ```csharp public partial class Images : ContentPage { public Images () { InitializeComponent(); imgLogo.Source = ImageSource.FromFile("my2.png"); } } ``` tn2>然后我们定义`ImageResource`图片资源扩展类,它实现了`IMarkupExtension`接口,该接口可以理解为实现任意资源在不同平台的扩展,后面还会讲到,在这个案例中我们只会让它返回图片资源就行了。 ```csharp [ContentProperty(nameof(Source))] public class ImageResourceExtension:IMarkupExtension { public string Source { get; set; } public object ProvideValue(IServiceProvider serviceProvider) { if (Source == null) return null; var imageSource = ImageSource.FromResource(Source, typeof(ImageResourceExtension).GetTypeInfo().Assembly); return imageSource; } } ``` tn2>然后我们在`App.xaml.cs`中设置Images为启动页面。 ```csharp MainPage = new Images(); ``` tn2>在安卓中测试运行如下: ![](https://img.tnblog.net/arcimg/hb/28d78fe3f8224acdbed023e4a34d4ce9.png) tn2>在IOS中测试运行如下: ![](https://img.tnblog.net/arcimg/hb/a34f2ae4d9814e47baaa943c7ca13a8f.png) tn2>我们发现它在IOS中并没有加载前两张图片,是因为那两张图片是来自安卓主机的本地中,而在IOS本地的资源中我们并没有进行定义。 ## IMarkupExtension tn2>可以通过从 `IMarkupExtension` 或 `IMarkupExtension<T>` 派生来定义自己的自定义 XAML 标记扩展。 如果标记扩展获取特定类型的值,则使用一般窗体。 下面是几 `Xamarin.Forms` 个标记扩展的情况: + `TypeExtension` 派生自 `IMarkupExtension<Type>` + `ArrayExtension` 派生自 `IMarkupExtension<Array>` + `DynamicResourceExtension` 派生自 `IMarkupExtension<DynamicResource>` + `BindingExtension` 派生自 `IMarkupExtension<BindingBase>` + `ConstraintExpression` 派生自 `IMarkupExtension<Constraint>` 这两个 `IMarkupExtension` 接口仅定义了一个名为 `ProvideValue` 的方法: ```csharp public interface IMarkupExtension { object ProvideValue(IServiceProvider serviceProvider); } public interface IMarkupExtension<out T> : IMarkupExtension { new T ProvideValue(IServiceProvider serviceProvider); } ``` tn2>由于 `IMarkupExtension<T> `派生自 `IMarkupExtension` 并且在上 `ProvideValue` 包含 new 关键字,因此它包含这两种 `ProvideValue` 方法。 通常,XAML 标记扩展定义用于返回值的属性。 (明显的例外是,在这 `ProvideValue` 种情况 `NullExtension` 下只返回 null 。 ) `ProvideValue` 方法具有一个类型 `IServiceProvider` 的参数,本文稍后将对此进行讨论。 >### 颜色扩展 tn2>以下 XAML 标记扩展允许你使用色调、饱和度和发光度组件来构造 Color 值。 它为颜色的四个分量定义四个属性,包括已初始化为1的 alpha 分量。 类从 `IMarkupExtension<Color>` 派生,以指示 Color 返回值: ```csharp public class MyColorExtension: IMarkupExtension<Color> { public double H { set; get; } public double S { set; get; } public double L { set; get; } public double A { set; get; } = 1.0; public Color ProvideValue(IServiceProvider serviceProvider) { return Color.FromHsla(H, S, L, A); } object IMarkupExtension.ProvideValue(IServiceProvider serviceProvider) { return (this as IMarkupExtension<Color>).ProvideValue(serviceProvider); } } ``` tn2>由于派生自 `IMarkupExtension` ,因此 `IMarkupExtension<T>` 该类必须包含两个 `ProvideValue` 方法,一个返回 `Color` ,另一个返回 `object` ,但第二个方法可以只调用第一个方法。 `"MyColor"`页显示了可在 XAML 文件中显示以指定的 BoxView 颜色的各种方式 `MyColorExtension` : ```csharp <?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:LableApp" x:Class="LableApp.MyColor" Title="My Color Demo"> <ContentPage.Resources> <ResourceDictionary> <Style TargetType="BoxView"> <Setter Property="WidthRequest" Value="80" /> <Setter Property="HeightRequest" Value="80" /> <Setter Property="HorizontalOptions" Value="Center" /> <Setter Property="VerticalOptions" Value="CenterAndExpand" /> </Style> </ResourceDictionary> </ContentPage.Resources> <StackLayout> <BoxView> <BoxView.Color> <local:MyColorExtension H="0" S="1" L="0.5" A="1" /> </BoxView.Color> </BoxView> <BoxView> <BoxView.Color> <local:MyColorExtension H="0.33" S="1" L="0.5" /> </BoxView.Color> </BoxView> <BoxView Color="{local:MyColorExtension H=0.67, S=1, L=0.5}" /> <BoxView Color="{local:MyColorExtension H=0, S=0, L=0.5}" /> <BoxView Color="{local:MyColorExtension A=0.5}" /> </StackLayout> </ContentPage> ``` tn2>请注意,当是 XML 标记时 MyColorExtension ,这四个属性被设置为属性,但当它出现在大括号之间时,这四个属性以逗号分隔,且不带引号。 、 S 和 L 的默认值 H 为0,的 A 默认值为1,因此,如果您希望它们设置为默认值,则可以省略这些属性。 最后一个示例显示一个示例,其中亮度为0,这通常会导致黑色,但 alpha 通道为0.5,因此它在页面的白色背景上呈灰色显示: ![](https://img.tnblog.net/arcimg/hb/78151b5fc4404d42aa3668f3713742cb.png)