Aracılığıyla paylaş


Xamarin.Forms özel işleyicisini .NET MAUI işleyicisine geçirme

Xamarin.Forms'da özel işleyiciler bir denetimin görünümünü ve davranışını özelleştirmek ve yeni platformlar arası denetimler oluşturmak için kullanılabilir. Her özel işleyicinin platformlar arası denetime bir başvurusu vardır ve genellikle özellik değişikliği bildirimleri göndermeye dayanır INotifyPropertyChanged . .NET Çok Platformlu Uygulama Kullanıcı Arabirimi (.NET MAUI), özel işleyiciler kullanmak yerine işleyici olarak adlandırılan yeni bir kavram getirir.

İşleyiciler, özel işleyiciler üzerinde birçok performans geliştirmesi sunar. Xamarin.Forms'da ViewRenderer sınıfı bir üst öğe oluşturur. Örneğin, Android'de yardımcı konumlandırma görevleri için kullanılan bir ViewGroup oluşturulur. .NET MAUI'de sınıfı, ViewHandler görsel hiyerarşisinin boyutunu azaltmaya ve uygulamanızın performansını geliştirmeye yardımcı olan bir üst öğe oluşturmaz. İşleyiciler ayrıca platform denetimlerini çerçeveden ayırır. Platform denetiminin yalnızca çerçevenin gereksinimlerini karşılaması gerekir. Bu yalnızca daha verimli olmakla kalmaz, gerektiğinde genişletmek veya geçersiz kılmak çok daha kolaydır. İşleyiciler, Comet ve Fabulous gibi diğer çerçeveler tarafından yeniden kullanıma da uygundur. İşleyiciler hakkında daha fazla bilgi için bkz . İşleyiciler.

Xamarin.Forms'da, OnElementChanged özel işleyicideki yöntemi platform denetimini oluşturur, varsayılan değerleri başlatır, olaylara abone olur ve işleyicinin eklendiği Xamarin.Forms öğesini (OldElement) ve işleyicinin (NewElement) eklendiği öğeyi işler. Ayrıca tek OnElementPropertyChanged bir yöntem, platformlar arası denetimde bir özellik değişikliği gerçekleştiğinde çağrılacak işlemleri tanımlar. .NET MAUI bu yaklaşımı basitleştirerek her özellik değişikliğinin ayrı bir yöntemle işlenmesini sağlar ve böylece platform denetimini oluşturma, denetim kurulumu gerçekleştirme ve denetim temizleme işlemlerini gerçekleştirmeye yönelik kod ayrı yöntemlere ayrılır.

Her platformdaki özel işleyiciler tarafından desteklenen bir Xamarin.Forms özel denetimini, her platformdaki bir işleyici tarafından desteklenen bir .NET MAUI özel denetimine geçirme işlemi aşağıdaki gibidir:

  1. Denetimin genel API'sini sağlayan platformlar arası denetim için bir sınıf oluşturun. Daha fazla bilgi için bkz . Platformlar arası denetim oluşturma.
  2. İşleyici partial sınıfı oluşturun. Daha fazla bilgi için bkz . İşleyiciyi oluşturma.
  3. İşleyici sınıfında, platformlar arası özellik değişiklikleri gerçekleştiğinde gerçekleştirecek eylemleri tanımlayan bir PropertyMapper sözlük oluşturun. Daha fazla bilgi için bkz . Özellik eşleyicisini oluşturma.
  4. Platformlar arası denetimi uygulayan yerel görünümleri oluşturan her platform için işleyici sınıfları oluşturun partial . Daha fazla bilgi için bkz . Platform denetimleri oluşturma.
  5. uygulamanızın MauiProgram sınıfında ve AddHandler yöntemlerini kullanarak ConfigureMauiHandlers işleyiciyi kaydedin. Daha fazla bilgi için bkz . İşleyiciyi kaydetme.

Daha sonra platformlar arası denetim kullanılabilir. Daha fazla bilgi için bkz . Platformlar arası denetimi kullanma.

Alternatif olarak, Xamarin.Forms denetimlerini özelleştiren özel işleyiciler dönüştürülebilir ve böylece .NET MAUI işleyicilerini değiştirebilirler. Daha fazla bilgi için bkz . denetimleri işleyicilerle özelleştirme.

Platformlar arası denetim oluşturma

Platformlar arası denetim oluşturmak için, öğesinden Viewtüretilen bir sınıf oluşturmanız gerekir:

namespace MyMauiControl.Controls
{
    public class CustomEntry : View
    {
        public static readonly BindableProperty TextProperty =
            BindableProperty.Create(nameof(Text), typeof(string), typeof(CustomEntry), null);

        public static readonly BindableProperty TextColorProperty =
            BindableProperty.Create(nameof(TextColor), typeof(Color), typeof(CustomEntry), null);

        public string Text
        {
            get { return (string)GetValue(TextProperty); }
            set { SetValue(TextProperty, value); }
        }

        public Color TextColor
        {
            get { return (Color)GetValue(TextColorProperty); }
            set { SetValue(TextColorProperty, value); }
        }
    }
}

Denetim, işleyicisi tarafından erişilecek bir genel API sağlamalı ve tüketicileri denetlemelidir. Platformlar arası denetimler, düzenleri ve görünümleri ekrana yerleştirmek için kullanılan bir görsel öğeyi temsil eden öğesinden Viewtüretilmelidir.

İşleyiciyi oluşturma

Platformlar arası denetiminizi oluşturduktan sonra işleyiciniz için bir partial sınıf oluşturmanız gerekir:

#if IOS || MACCATALYST
using PlatformView = Microsoft.Maui.Platform.MauiTextField;
#elif ANDROID
using PlatformView = AndroidX.AppCompat.Widget.AppCompatEditText;
#elif WINDOWS
using PlatformView = Microsoft.UI.Xaml.Controls.TextBox;
#elif (NETSTANDARD || !PLATFORM) || (NET6_0_OR_GREATER && !IOS && !ANDROID)
using PlatformView = System.Object;
#endif
using MyMauiControl.Controls;
using Microsoft.Maui.Handlers;

namespace MyMauiControl.Handlers
{
    public partial class CustomEntryHandler
    {
    }
}

İşleyici sınıfı, uygulaması ek bir kısmi sınıfla her platformda tamamlanacak kısmi bir sınıftır.

Koşullu using deyimler, her platformda türü tanımlar PlatformView . Son koşullu using deyim, değerine System.Objecteşit olduğunu tanımlarPlatformView. Bu, türün tüm platformlardaki PlatformView kullanım için işleyici içinde kullanılabilmesi için gereklidir. Alternatif olarak, koşullu derleme kullanarak özelliği platform başına bir kez tanımlamanız PlatformView gerekir.

Özellik eşleyicisi oluşturma

Her işleyici genellikle platformlar arası denetimde bir özellik değişikliği gerçekleştiğinde hangi Eylemlerin gerçekleştireceğini tanımlayan bir özellik eşleyicisi sağlar. Tür PropertyMapper , platformlar arası denetimin özelliklerini ilişkili Eylemleriyle eşleyen bir Dictionary türdür.

Dekont

Özellik eşleyicisi, Xamarin.Forms özel işleyicisindeki yöntemin OnElementPropertyChanged yerini alır.

PropertyMapper .NET MAUI'nin genel ViewHandler sınıfında tanımlanır ve iki genel bağımsız değişkenin sağlanmasını gerektirir:

  • platformlar arası denetimin sınıfından Viewtüretilir.
  • İşleyici için sınıfı.

Aşağıdaki kod örneği, tanımıyla PropertyMapper genişletilmiş sınıfı gösterirCustomEntryHandler:

public partial class CustomEntryHandler
{
    public static PropertyMapper<CustomEntry, CustomEntryHandler> PropertyMapper = new PropertyMapper<CustomEntry, CustomEntryHandler>(ViewHandler.ViewMapper)
    {
        [nameof(CustomEntry.Text)] = MapText,
        [nameof(CustomEntry.TextColor)] = MapTextColor
    };

    public CustomEntryHandler() : base(PropertyMapper)
    {
    }
}

PropertyMapper, Dictionary anahtarı a string olan ve değeri genel Actionolan bir değeridir. , string platformlar arası denetimin özellik adını, Action işleyici ve platformlar arası denetimi bağımsız değişken olarak gerektiren bir static yöntemi temsil eder. Örneğin, yönteminin MapText imzası şeklindedir public static void MapText(CustomEntryHandler handler, CustomEntry view).

Her platform işleyicisi, yerel görünüm API'lerini işleyen Eylemlerin uygulamalarını sağlamalıdır. Bu, bir özellik platformlar arası denetimde ayarlandığında temel alınan yerel görünümün gerektiği gibi güncelleştirilmesini sağlar. Bu yaklaşımın avantajı, özellik eşleyicisi alt sınıflama olmadan platformlar arası denetim tüketicileri tarafından değiştirilebildiği için kolay platformlar arası denetim özelleştirmesine olanak sağlamasıdır. Daha fazla bilgi için bkz . denetimleri işleyicilerle özelleştirme.

Platform denetimlerini oluşturma

İşleyiciniz için eşleyicileri oluşturduktan sonra tüm platformlarda işleyici uygulamaları sağlamanız gerekir. Bu, Platforms klasörünün alt klasörlerine kısmi sınıf işleyicisi uygulamaları eklenerek gerçekleştirilebilir. Alternatif olarak projenizi dosya adı tabanlı çoklu hedeflemeyi veya klasör tabanlı çoklu hedeflemeyi ya da her ikisini de destekleyecek şekilde yapılandırabilirsiniz.

Dosya adı tabanlı çoklu hedefleme, düğümün alt öğeleri <Project> olarak proje dosyasına aşağıdaki XML eklenerek yapılandırılır:

<!-- Android -->
<ItemGroup Condition="$(TargetFramework.StartsWith('net8.0-android')) != true">
  <Compile Remove="**\*.Android.cs" />
  <None Include="**\*.Android.cs" Exclude="$(DefaultItemExcludes);$(DefaultExcludesInProjectFolder)" />
</ItemGroup>

<!-- iOS and Mac Catalyst -->
<ItemGroup Condition="$(TargetFramework.StartsWith('net8.0-ios')) != true AND $(TargetFramework.StartsWith('net8.0-maccatalyst')) != true">
  <Compile Remove="**\*.MaciOS.cs" />
  <None Include="**\*.MaciOS.cs" Exclude="$(DefaultItemExcludes);$(DefaultExcludesInProjectFolder)" />
</ItemGroup>

<!-- Windows -->
<ItemGroup Condition="$(TargetFramework.Contains('-windows')) != true ">
  <Compile Remove="**\*.Windows.cs" />
  <None Include="**\*.Windows.cs" Exclude="$(DefaultItemExcludes);$(DefaultExcludesInProjectFolder)" />
</ItemGroup>

Çoklu hedeflemeyi yapılandırma hakkında daha fazla bilgi için bkz . Çoklu hedeflemeyi yapılandırma.

Her platform işleyici sınıfı kısmi bir sınıf olmalı ve iki tür bağımsız değişken gerektiren genel ViewHandler sınıftan türetilmelidir:

  • platformlar arası denetimin sınıfından Viewtüretilir.
  • Platformda platformlar arası denetimi uygulayan yerel görünümün türü. Bu, işleyicideki özelliğin PlatformView türüyle aynı olmalıdır.

Önemli

ViewHandler sınıfı ve PlatformView özellikleri sağlarVirtualView. VirtualView özelliği, işleyicisinden platformlar arası denetime erişmek için kullanılır. PlatformView özelliği, platformlar arası denetimi uygulayan her platformda yerel görünüme erişmek için kullanılır.

Platform işleyicisi uygulamalarının her biri aşağıdaki yöntemleri geçersiz kılmalıdır:

  • CreatePlatformView, platformlar arası denetimi uygulayan yerel görünümü oluşturup döndürmelidir.
  • ConnectHandler, yerel görünümü başlatma ve olay aboneliklerini gerçekleştirme gibi herhangi bir yerel görünüm kurulumu gerçekleştirmelidir.
  • DisconnectHandler, olaylardan aboneliği kaldırma ve nesneleri yok etme gibi herhangi bir yerel görünüm temizlemesi gerçekleştirmelidir. Bu yöntem kasıtlı olarak .NET MAUI tarafından çağrılmıyor. Bunun yerine, uygulamanızın yaşam döngüsünde uygun bir konumdan kendiniz çağırmanız gerekir. Daha fazla bilgi için bkz . Yerel görünüm temizleme.

Dekont

CreatePlatformView, ConnectHandlerve DisconnectHandler geçersiz kılmaları, Xamarin.Forms özel işleyicisindeki yöntemin OnElementChanged yerine geçer.

Her platform işleyicisi, eşleyici sözlüklerinde tanımlanan Eylemleri de uygulamalıdır. Ayrıca her platform işleyicisi, platform üzerinde platformlar arası denetimin işlevselliğini uygulamak için gerektiği gibi kod sağlamalıdır. Alternatif olarak, daha karmaşık denetimler için bu ek bir tür tarafından sağlanabilir.

Aşağıdaki örnekte Android'de CustomEntryHandler uygulama gösterilmektedir:

#nullable enable
using AndroidX.AppCompat.Widget;
using Microsoft.Maui.Handlers;
using Microsoft.Maui.Platform;
using MyMauiControl.Controls;

namespace MyMauiControl.Handlers
{
    public partial class CustomEntryHandler : ViewHandler<CustomEntry, AppCompatEditText>
    {
        protected override AppCompatEditText CreatePlatformView() => new AppCompatEditText(Context);

        protected override void ConnectHandler(AppCompatEditText platformView)
        {
            base.ConnectHandler(platformView);

            // Perform any control setup here
        }

        protected override void DisconnectHandler(AppCompatEditText platformView)
        {
            // Perform any native view cleanup here
            platformView.Dispose();
            base.DisconnectHandler(platformView);
        }

        public static void MapText(CustomEntryHandler handler, CustomEntry view)
        {
            handler.PlatformView.Text = view.Text;
            handler.PlatformView?.SetSelection(handler.PlatformView?.Text?.Length ?? 0);
        }

        public static void MapTextColor(CustomEntryHandler handler, CustomEntry view)
        {
            handler.PlatformView?.SetTextColor(view.TextColor.ToPlatform());
        }
    }
}

CustomEntryHandler sınıfından ViewHandler türetilir ve CustomEntry genel bağımsız değişken platformlar arası denetim türünü ve AppCompatEditText bağımsız değişken yerel denetimin türünü belirtir.

Geçersiz CreatePlatformView kılma bir AppCompatEditText nesne oluşturur ve döndürür. Geçersiz ConnectHandler kılma, gerekli yerel görünüm ayarlarını gerçekleştirmek için konumdur. Geçersiz DisconnectHandler kılma, herhangi bir yerel görünüm temizleme işlemini gerçekleştirmek için konumdur ve bu nedenle örnekte yöntemini AppCompatEditText çağırırDispose.

İşleyici ayrıca özellik eşleyici sözlüğünde tanımlanan Eylemleri uygular. Her Eylem, platformlar arası denetimde değişen bir özelliğe yanıt olarak yürütülür ve bağımsız değişken olarak işleyici ve platformlar arası denetim örnekleri gerektiren bir static yöntemdir. Her durumda, Eylem yerel denetimde tanımlanan yöntemleri çağırır.

İşleyiciyi kaydetme

Bir özel denetimin ve işleyicinin, bir uygulamanın tüketilmesi için önce bir uygulamaya kaydedilmesi gerekir. Bu, uygulamanın platformlar arası giriş noktası olan uygulama projenizdeki sınıfındaki yönteminde MauiProgram gerçekleşmelidirCreateMauiApp:

using Microsoft.Extensions.Logging;
using MyMauiControl.Controls;
using MyMauiControl.Handlers;

namespace MyMauiControl;

public static class MauiProgram
{
  public static MauiApp CreateMauiApp()
  {
    var builder = MauiApp.CreateBuilder();
    builder
      .UseMauiApp<App>()
      .ConfigureFonts(fonts =>
      {
        fonts.AddFont("OpenSans-Regular.ttf", "OpenSansRegular");
        fonts.AddFont("OpenSans-Semibold.ttf", "OpenSansSemibold");
      })
      .ConfigureMauiHandlers(handlers =>
      {
        handlers.AddHandler(typeof(CustomEntry), typeof(CustomEntryHandler));
      });

#if DEBUG
    builder.Logging.AddDebug();
#endif

    return builder.Build();
  }
}

İşleyici ve AddHandler yöntemiyle ConfigureMauiHandlers kaydedilir. Yöntemin AddHandler ilk bağımsız değişkeni platformlar arası denetim türüdür ve ikinci bağımsız değişken de işleyici türüdür.

Dekont

Bu kayıt yaklaşımı, yavaş ve pahalı olan Xamarin.Forms derleme taramasından kaçınır.

Platformlar arası denetimi kullanma

İşleyiciyi uygulamanızla kaydettikten sonra platformlar arası denetim kullanılabilir:

<ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             xmlns:controls="clr-namespace:MyMauiControl.Controls"
             x:Class="MyMauiControl.MainPage">
    <Grid>
        <controls:CustomEntry Text="Hello world"
                              TextColor="Blue" />
    </Grid>
</ContentPage>

Yerel görünüm temizleme

Her platformun işleyici uygulaması, olaylardan abonelikten çıkarma ve nesneleri yok etme gibi yerel görünüm temizleme gerçekleştirmek için kullanılan uygulamayı geçersiz kılar DisconnectHandler . Ancak, bu geçersiz kılma kasıtlı olarak .NET MAUI tarafından çağrılmıyor. Bunun yerine, uygulamanızın yaşam döngüsünde uygun bir konumdan kendiniz çağırmanız gerekir. Bu durum, denetimi içeren sayfanın bulunduğu sayfadan uzaklaştığında olabilir ve bu da sayfanın Unloaded olayının tetiklenmesine neden olabilir.

Sayfanın Unloaded olayı için bir olay işleyicisi XAML'ye kaydedilebilir:

<ContentPage ...
             xmlns:controls="clr-namespace:MyMauiControl.Controls"
             Unloaded="ContentPage_Unloaded">
    <Grid>
        <controls:CustomEntry x:Name="customEntry"
                              ... />
    </Grid>
</ContentPage>

Daha sonra olayın olay işleyicisi Unloaded , örneğinde DisconnectHandlerHandler yöntemini çağırabilir:

void ContentPage_Unloaded(object sender, EventArgs e)
{
    customEntry.Handler?.DisconnectHandler();
}

Ayrıca bkz.