创建 Xamarin.Forms 视觉对象呈现器

使用 Xamarin.Forms 视觉对象,可以创建呈现器并将其选择性地应用于 VisualElement 对象,无需子类化 Xamarin.Forms 视图。 将使用一个可指定 IVisual 类型(作为其 ExportRendererAttribute 的一部分)的呈现器而不是默认呈现器来呈现选择加入的视图。 进行呈现器选择时,将在呈现器选择过程中检查视图的 Visual 属性并将其包含在内。

重要

目前,在呈现视图后,无法更改 Visual 属性,但未来的版本会改变这一点。

创建和使用 Xamarin.Forms 视觉对象呈现器的过程如下:

  1. 为所需视图创建平台呈现器。 有关详细信息,请参阅创建呈现器
  2. 创建一个从 IVisual 派生的类型。 有关详细信息,请参阅创建 IVisual 类型
  3. IVisual 类型注册为装饰呈现器的 ExportRendererAttribute 的一部分。 有关详细信息,请参阅注册 IVisual 类型
  4. 通过将视图上的 Visual 属性设置为 IVisual 名称来使用视觉对象呈现器。 有关详细信息,请参阅使用 IVisual 呈现器
  5. [可选] 为 IVisual 类型注册一个名称。 有关详细信息,请参阅为 IVisual 类型注册一个名称

创建平台呈现器

若要了解如何创建呈现器类,请参阅自定义呈现器。 但请注意,Xamarin.Forms 视觉对象呈现器无需子类化视图即可应用于视图。

此处概述的呈现器类实现了一个自定义的 Button,它显示带阴影的文本。

iOS

以下代码示例展示了适用于 iOS 的按钮呈现器:

public class CustomButtonRenderer : ButtonRenderer
{
    protected override void OnElementChanged(ElementChangedEventArgs<Button> e)
    {
        base.OnElementChanged(e);

        if (e.OldElement != null)
        {
            // Cleanup
        }

        if (e.NewElement != null)
        {
            Control.TitleShadowOffset = new CoreGraphics.CGSize(1, 1);
            Control.SetTitleShadowColor(Color.Black.ToUIColor(), UIKit.UIControlState.Normal);
        }
    }
}

Android

以下代码示例展示了适用于 Android 的按钮呈现器:

public class CustomButtonRenderer : Xamarin.Forms.Platform.Android.AppCompat.ButtonRenderer
{
    public CustomButtonRenderer(Context context) : base(context)
    {
    }

    protected override void OnElementChanged(ElementChangedEventArgs<Button> e)
    {
        base.OnElementChanged(e);

        if (e.OldElement != null)
        {
            // Cleanup
        }

        if (e.NewElement != null)
        {
            Control.SetShadowLayer(5, 3, 3, Color.Black.ToAndroid());
        }
    }
}

创建 IVisual 类型

在跨平台库中,创建一个派生自 IVisual 的类型:

public class CustomVisual : IVisual
{
}

然后可以针对呈现器类注册 CustomVisual 类型,从而允许 Button 对象选择使用呈现器。

注册 IVisual 类型

在平台项目中,在程序集级别添加 ExportRendererAttribute

[assembly: ExportRenderer(typeof(Xamarin.Forms.Button), typeof(CustomButtonRenderer), new[] { typeof(CustomVisual) })]
namespace VisualDemos.iOS
{
    public class CustomButtonRenderer : ButtonRenderer
    {
        protected override void OnElementChanged(ElementChangedEventArgs<Button> e)
        {
            // ...
        }
    }
}

在 iOS 平台项目的这个示例中,ExportRendererAttribute 指定 CustomButtonRenderer 类将用于呈现使用 Button 对象,将 IVisual 类型注册为第三个参数。 将使用一个可指定 IVisual 类型(作为其 ExportRendererAttribute 的一部分)的呈现器而不是默认呈现器来呈现选择加入的视图。

使用视觉对象呈现器

Button 对象可以通过将其 Visual 属性设置为 Custom 来选择使用呈现器类:

<Button Visual="Custom"
        Text="CUSTOM BUTTON"
        BackgroundColor="{StaticResource PrimaryColor}"
        TextColor="{StaticResource SecondaryTextColor}"
        HorizontalOptions="FillAndExpand" />

注意

在 XAML 中,使用类型转换器就无需在 Visual 属性值中包含“Visual”后缀。 但是,也可以指定完整的类型名称。

等效 C# 代码如下:

Button button = new Button { Text = "CUSTOM BUTTON", ... };
button.Visual = new CustomVisual();

进行呈现器选择时,将在呈现器选择过程中检查 ButtonVisual 属性并将其包含在内。 如果未找到呈现器,则使用 Xamarin.Forms 默认呈现器。

以下屏幕截图显示了呈现的 Button,它显示带阴影的文本:

iOS 和 Android 上带有阴影文本的自定义按钮的屏幕截图

为 IVisual 类型注册一个名称

VisualAttribute 可用于选择性地为 IVisual 类型注册一个不同的名称。 可以使用此方法来解决不同视觉对象库之间的命名冲突,也可以在你只想使用与其类型名称不同的名称引用视觉对象的情况下使用此方法。

应在跨平台库中的或平台项目中的程序集级别定义 VisualAttribute

[assembly: Visual("MyVisual", typeof(CustomVisual))]

然后,可以通过注册的名称使用 IVisual 类型:

<Button Visual="MyVisual"
        ... />

注意

通过注册的名称使用视觉对象时,必须包含任何“Visual”后缀。