MAUI 移植 Xamarin.Forms 自定義渲染器

微軟技術棧發表於2021-12-28

大家好,我是本期的微軟MVP實驗室研究員——周豪。本篇文章主要介紹如何移植現有的Xamarin CustomRenderer在新的MAUI專案使用。接下來就讓我們一起到實驗室中一探究竟吧!

image.png

簡介

眾所周知,.NET MAUI使用的是Handler處理程式,而Xamarin使用的則是Render渲染器模式。儘管MAUI中使用了新的渲染模式,但仍然相容Xamarin當中的自定義渲染器,這意味著如果你的專案是從Xamarin移植到MAUI當中,大部分程式碼能夠可以重用,本篇文章介紹如何將Xamarin 渲染器(Render)移植到.NET MAUI專案當中。

先決條件

為了還原本次測試環境,下面說明了本次測試的開發環境,如下:

IDE: Visual Studio Community 2022 Preview (64 位) 17.0.0 Preview 7.0

作業系統: Windows 11家庭版 已安裝Andoroid子系統(除錯使用)

IDE 模組:安裝Xamarin移動端開發環境及MAUI預覽版環境

建立Xamarin渲染器

第一步

首先建立一個Xamarin.Forms專案,在Android專案中建立CustomRender資料夾,並且建立自定義渲染器MyButtonRende,如下所示:

cc7b1451177abb9a1390b3e63c67aff2.png

說明: MyButtonRender類完整程式碼如下所示:

using Android.Content; 
using App2.Droid.CustomRender; 
using Xamarin.Forms;
using Xamarin.Forms.Platform.Android;
using App2;

[assembly: ExportRenderer(typeof(MyButton), typeof(MyButtonRender))]
namespace App2.Droid.CustomRender
{
    public class MyButtonRender : ButtonRenderer
    {
        public MyButtonRender(Context context) : base(context)
        {
        }

        protected override void OnElementChanged(ElementChangedEventArgs<Xamarin.Forms.Button> e)
        {
            base.OnElementChanged(e);
            if(Control!= null)
            {
                Control.SetBackgroundColor(global::Android.Graphics.Color.Red);
            }
        }
    }
}

第二步

在類庫專案App2中新增MyButton類,繼承Button,如下所示:


using Xamarin.Forms;

namespace App2
{
    public class MyButton : Button
    {

    }
}

第三步

在Xaml中使用MyButton,如下所示:

<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             x:Class="App2.Views.AboutPage"
             xmlns:my="clr-namespace:App2" >
   <Grid>
    
    <!--此處略過許多程式碼-->

    <my:MyButton Text="About!" />
  </Grid>
</ContentPage>

第四步

啟動Android專案,預覽效果,如下所示:

4b83d2eba01e6010670bc491b519dae4.png

說明:通過上面幾步,我們輕鬆的完成了在Xamarin當中自定義渲染器並且顯示在模擬器當中,接下來,主要的任務是將Xamarin現有的自定義渲染器移植到MAUI專案中,那麼下面接著繼續表演。

渲染器移植至MAUI專案

第一步

這裡,直接建立名為MAUIRender的新MAUI專案

39802fe03053a0783f10d01fb81b97e2.png

第二步

然後,我們把Xamarin中建立的MyButton與MyButtonRender直接複製到MAUI的專案中,如下所示:

89b42494de01d7b7d537666bd6c7aff5.png

MyButtonRender類修改如下:

using App2;
using Android.Content; 
using Microsoft.Maui.Controls.Platform;
using Microsoft.Maui.Controls;
using Microsoft.Maui.Controls.Compatibility.Platform.Android.FastRenderers;

namespace MAUIRender
{
    public class MyButtonRender : ButtonRenderer
    {
        public MyButtonRender(Context context) : base(context)
        {
        }

        protected override void OnElementChanged(ElementChangedEventArgs<Button> e)
        {
            base.OnElementChanged(e);
            if(Control!= null)
                Control.SetBackgroundColor(global::Android.Graphics.Color.Red);
        }
    }
}

說明: 此處更新涉及更新名稱空間引用

  • 移除舊的Xamarin引用:
    using Xamarin.Forms.Platform.Android;
    using Xamarin.Forms;
  • 新增新的MAUI引用:
    using Microsoft.Maui.Controls;
    using Microsoft.Maui.Controls.Platform;
    using Microsoft.Maui.Controls.Compatibility.Platform.Android.AppCompat;

移除 [assembly: ExportRenderer(typeof(MyButton), typeof(MyButtonRender))] (原因下面說)
MyButton類修改如下:

using Microsoft.Maui.Controls;

namespace App2
{
    public class MyButton : Button
    {

    }
}

說明:using Xamarin.Forms; 更新為: using Microsoft.Maui.Controls;

第三步

依賴注入自定義的Render

上面所講到移除 [assembly: ExportRenderer(typeof(MyButton),typeof(MyButtonRender))] 宣告,在Xamarin當中,渲染器強制宣告在Android專案中,耦合性很強。這一點,在MAUI專案當中,則是通過Startup類中依賴注入的形式新增,通過擴充套件方法 ConfigureMauiHandlers 新增 AddCompatibilityRenderer,如下所示:

public static MauiApp CreateMauiApp()
        {
            var builder = MauiApp.CreateBuilder();
            builder
                .UseMauiApp<App>()
                .ConfigureFonts(fonts =>
                {
                    fonts.AddFont("OpenSans-Regular.ttf", "OpenSansRegular");
                })
                .ConfigureMauiHandlers(handler =>
                {
                #if ANDROID
                handler.AddCompatibilityRenderer(typeof(MyButton), typeof(MyButtonRender));
                #endif
                });

      return builder.Build();
    }

說明: 之所以使用ANDROID 條件,取決於我們併為定義IOS平臺的自定義渲染器,當然我們可以這麼做,如果當該渲染器僅僅為Android提供,我們即可單獨設定。

第四步

XAML頁面中新增MyButton名稱空間,宣告MyBuToon,如下所示:

<ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             x:Class="MAUIRender.MainPage"
             xmlns:my="clr-namespace:MAUIRender"
             BackgroundColor="{DynamicResource SecondaryColor}">
    <Grid>
        <my:MyButton Text="Hello,MyButton!!!"
                     HeightRequest="80"
                     WidthRequest="300"
                     HorizontalOptions="Center"
                     />
    </Grid>
</ContentPage>

最終執行效果圖,如下所示:

1706e39161099adc0d152d47a4fe91ae.png

總結

這篇文章主要給大家介紹瞭如何將Xamarin Render移植到 .NET MAUI專案當中,當然在新的MAUI當中,仍然建議大家使用新的Handler處理程式來實現,並且它提供了更好的效能以及靈活性。

bc93fde364ea9dd3d9106b58e805b770.png

微軟最有價值專家是微軟公司授予第三方技術專業人士的一個全球獎項。28年來,世界各地的技術社群領導者,因其線上上和線下的技術社群中分享專業知識和經驗而獲得此獎項。

MVP是經過嚴格挑選的專家團隊,他們代表著技術最精湛且最具智慧的人,是對社群投入極大的熱情並樂於助人的專家。MVP致力於通過演講、論壇問答、建立網站、撰寫部落格、分享視訊、開源專案、組織會議等方式來幫助他人,並最大程度地幫助微軟技術社群使用者使用Microsoft技術。
更多詳情請登入官方網站:
https://mvp.microsoft.com/zh-cn


歡迎關注微軟中國MSDN訂閱號,獲取更多最新發布!
image.png

相關文章