Sdílet prostřednictvím


Přizpůsobení ovládacích prvků pomocí obslužných rutin

Projděte si ukázku. Procházení ukázky

Obslužné rutiny je možné přizpůsobit, aby se rozšířil vzhled a chování ovládacího prvku napříč platformami nad rámec přizpůsobení, které je možné prostřednictvím rozhraní API ovládacího prvku. Toto přizpůsobení, které upravuje nativní zobrazení pro řízení napříč platformami, se dosahuje úpravou mapperu pro obslužnou rutinu pomocí jedné z následujících metod:

  • PrependToMapping, který upraví mapovač pro obslužnou rutinu před použití mapování ovládacích prvků .NET MAUI.
  • ModifyMapping, který upraví existující mapování.
  • AppendToMapping, který upraví mapovač pro obslužnou rutinu po použití mapování ovládacích prvků .NET MAUI.

Každá z těchto metod má identický podpis, který vyžaduje dva argumenty:

  • Klíč stringzaložený na klíči. Při úpravě jednoho z mapování poskytovaných rozhraním .NET MAUI je nutné zadat klíč používaný rozhraním .NET MAUI. Hodnoty klíčů používané mapováním ovládacích prvků .NET MAUI jsou založené na názvech rozhraní a vlastností, například nameof(IEntry.IsPassword). Rozhraní a jejich vlastnosti, které abstrahují jednotlivé multiplatformní ovládací prvky, najdete tady. Jedná se o formát klíče, který byste měli použít, pokud chcete, aby se přizpůsobení obslužné rutiny spustilo při každé změně vlastnosti. Jinak může být klíč libovolnou hodnotou, která nemusí odpovídat názvu vlastnosti vystavené typem. Můžete například MyCustomization zadat jako klíč s případnou úpravou nativního zobrazení, která se provádí jako vlastní nastavení. Následkem tohoto formátu klíče je však to, že přizpůsobení obslužné rutiny se spustí pouze při první úpravě mapovače obslužné rutiny.
  • Představuje Action metodu, která provádí přizpůsobení obslužné rutiny. Určuje Action dva argumenty:
    • Argument handler , který poskytuje instanci obslužné rutiny, která je přizpůsobena.
    • Argument view , který poskytuje instanci multiplatformního ovládacího prvku, který obslužná rutina implementuje.

Důležité

Přizpůsobení obslužné rutiny jsou globální a nejsou vymezeny na konkrétní instanci ovládacího prvku. Přizpůsobení obslužné rutiny může probíhat kdekoli ve vaší aplikaci. Jakmile je obslužná rutina přizpůsobená, ovlivní všechny ovládací prvky tohoto typu všude ve vaší aplikaci.

Každá třída obslužné rutiny zveřejňuje nativní zobrazení pro řízení napříč platformami prostřednictvím své PlatformView vlastnosti. Tato vlastnost je přístupná k nastavení nativních vlastností zobrazení, vyvolání nativních metod zobrazení a přihlášení k odběru událostí nativního zobrazení. Kromě toho je řízení napříč platformami implementované obslužnou rutinou zpřístupněno prostřednictvím jeho VirtualView vlastnosti.

Obslužné rutiny je možné přizpůsobit pro každou platformu pomocí podmíněné kompilace na více cílový kód založený na platformě. Případně můžete pomocí částečných tříd uspořádat kód do složek a souborů specifických pro platformu. Další informace o podmíněné kompilaci naleznete v tématu Podmíněné kompilace.

Přizpůsobení ovládacího prvku

Zobrazení .NET MAUI Entry je jednořádkový ovládací prvek pro zadávání textu, který implementuje IEntry rozhraní. Zobrazení EntryHandler se mapuje Entry na následující nativní zobrazení pro každou platformu:

  • iOS/Mac Catalyst: UITextField
  • Android: AppCompatEditText
  • Windows: TextBox

Následující diagramy znázorňují, jak Entry je zobrazení mapováno na jeho nativní zobrazení prostřednictvím EntryHandler:

Architektura obslužné rutiny zadávání

Mapovač Entry vlastností ve EntryHandler třídě mapuje vlastnosti ovládacího prvku napříč platformami na nativní rozhraní API pro zobrazení. Tím se zajistí, že když je vlastnost nastavena Entryna , základní nativní zobrazení se aktualizuje podle potřeby.

Mapovač vlastností lze upravit tak, aby se přizpůsobil Entry na jednotlivých platformách:

namespace CustomizeHandlersDemo.Views;

public partial class CustomizeEntryPage : ContentPage
{
    public CustomizeEntryPage()
    {
        InitializeComponent();
        ModifyEntry();
    }

    void ModifyEntry()
    {
        Microsoft.Maui.Handlers.EntryHandler.Mapper.AppendToMapping("MyCustomization", (handler, view) =>
        {
#if ANDROID
            handler.PlatformView.SetSelectAllOnFocus(true);
#elif IOS || MACCATALYST
            handler.PlatformView.EditingDidBegin += (s, e) =>
            {
                handler.PlatformView.PerformSelector(new ObjCRuntime.Selector("selectAll"), null, 0.0f);
            };
#elif WINDOWS
            handler.PlatformView.GotFocus += (s, e) =>
            {
                handler.PlatformView.SelectAll();
            };
#endif
        });
    }
}

V tomto příkladu Entry se přizpůsobení provádí ve třídě stránky. Proto se všechny Entry ovládací prvky na Androidu, iOSu a Windows přizpůsobí po vytvoření instance CustomizeEntryPage . Vlastní nastavení se provádí přístupem k vlastnosti obslužných PlatformView rutin, která poskytuje přístup k nativnímu zobrazení, které se mapuje na řízení napříč platformami na jednotlivých platformách. Nativní kód pak přizpůsobí obslužnou rutinu tak, že vybere veškerý text v textu, Entry když získá fokus.

Další informace o mapovačích naleznete v tématu Mappers.

Přizpůsobení konkrétní instance ovládacího prvku

Obslužné rutiny jsou globální a přizpůsobení obslužné rutiny ovládacího prvku způsobí přizpůsobení všech ovládacích prvků stejného typu v aplikaci. Obslužné rutiny pro konkrétní instance ovládacího prvku je však možné přizpůsobit podtřídou ovládacího prvku a potom úpravou obslužné rutiny pro základní typ ovládacího prvku pouze v případě, že je ovládací prvek typu podtřídy. Pokud chcete například přizpůsobit konkrétní Entry ovládací prvek na stránce, která obsahuje více Entry ovládacích prvků, měli byste nejprve podtřídu Entry ovládacího prvku:

namespace CustomizeHandlersDemo.Controls
{
    internal class MyEntry : Entry
    {
    }
}

Potom můžete upravit EntryHandlervlastnost pomocí mapovače vlastností a provést požadovanou úpravu pouze instancím MyEntry :

Microsoft.Maui.Handlers.EntryHandler.Mapper.AppendToMapping("MyCustomization", (handler, view) =>
{
    if (view is MyEntry)
    {
#if ANDROID
        handler.PlatformView.SetSelectAllOnFocus(true);
#elif IOS || MACCATALYST
        handler.PlatformView.EditingDidBegin += (s, e) =>
        {
            handler.PlatformView.PerformSelector(new ObjCRuntime.Selector("selectAll"), null, 0.0f);
        };
#elif WINDOWS
        handler.PlatformView.GotFocus += (s, e) =>
        {
            handler.PlatformView.SelectAll();
        };
#endif
    }
});

Pokud se přizpůsobení obslužné rutiny provádí ve vaší App třídě, MyEntry všechny instance v aplikaci se přizpůsobí podle úprav obslužné rutiny.

Přizpůsobení ovládacího prvku pomocí životního cyklu obslužné rutiny

Všechny ovládací prvky .NET MAUI založené na obslužné rutině podporují HandlerChanging a HandlerChanged události. Událost HandlerChanged je vyvolána v případě, že nativní zobrazení, které implementuje multiplatformní řízení, je k dispozici a inicializováno. Událost HandlerChanging se vyvolá, když obslužná rutina ovládacího prvku bude odebrána z řízení mezi platformami. Další informace o událostech životního cyklu obslužné rutiny naleznete v tématu Životní cyklus obslužné rutiny.

Životní cyklus obslužné rutiny lze použít k přizpůsobení obslužné rutiny. Pokud se například chcete přihlásit k odběru událostí nativního zobrazení a odhlásit odběr, musíte zaregistrovat obslužné rutiny událostí pro HandlerChangedHandlerChanging přizpůsobení ovládacího prvku pro různé platformy:

<Entry HandlerChanged="OnEntryHandlerChanged"
       HandlerChanging="OnEntryHandlerChanging" />

Obslužné rutiny lze přizpůsobit na platformu pomocí podmíněné kompilace nebo pomocí částečných tříd pro uspořádání kódu do složek a souborů specifických pro platformu. Každý přístup se bude dále probírat přizpůsobením textu Entry tak, aby byl vybrán veškerý jeho text, když získá fokus.

Podmíněná kompilace

Soubor kódu obsahující obslužné rutiny událostí pro HandlerChanged události a HandlerChanging události se zobrazí v následujícím příkladu, který používá podmíněnou kompilaci:

#if ANDROID
using AndroidX.AppCompat.Widget;
#elif IOS || MACCATALYST
using UIKit;
#elif WINDOWS
using Microsoft.UI.Xaml.Controls;
using Microsoft.UI.Xaml;
#endif

namespace CustomizeHandlersDemo.Views;

public partial class CustomizeEntryHandlerLifecyclePage : ContentPage
{
    public CustomizeEntryHandlerLifecyclePage()
    {
        InitializeComponent();
    }

    void OnEntryHandlerChanged(object sender, EventArgs e)
    {
        Entry entry = sender as Entry;
#if ANDROID
        (entry.Handler.PlatformView as AppCompatEditText).SetSelectAllOnFocus(true);
#elif IOS || MACCATALYST
        (entry.Handler.PlatformView as UITextField).EditingDidBegin += OnEditingDidBegin;
#elif WINDOWS
        (entry.Handler.PlatformView as TextBox).GotFocus += OnGotFocus;
#endif
    }

    void OnEntryHandlerChanging(object sender, HandlerChangingEventArgs e)
    {
        if (e.OldHandler != null)
        {
#if IOS || MACCATALYST
            (e.OldHandler.PlatformView as UITextField).EditingDidBegin -= OnEditingDidBegin;
#elif WINDOWS
            (e.OldHandler.PlatformView as TextBox).GotFocus -= OnGotFocus;
#endif
        }
    }

#if IOS || MACCATALYST                   
    void OnEditingDidBegin(object sender, EventArgs e)
    {
        var nativeView = sender as UITextField;
        nativeView.PerformSelector(new ObjCRuntime.Selector("selectAll"), null, 0.0f);
    }
#elif WINDOWS
    void OnGotFocus(object sender, RoutedEventArgs e)
    {
        var nativeView = sender as TextBox;
        nativeView.SelectAll();
    }
#endif
}

Událost HandlerChanged je vyvolána po nativním zobrazení, které implementuje multiplatformní řízení bylo vytvořeno a inicializováno. Proto je obslužná rutina události tam, kde se mají provádět odběry nativních událostí. To vyžaduje přetypování PlatformView vlastnosti obslužné rutiny na typ nebo základní typ nativního zobrazení, aby bylo možné získat přístup k nativním událostem. V tomto příkladu v iOSu, Mac Catalyst a Windows se událost přihlásí k odběru nativních událostí zobrazení, které jsou vyvolány v případě nativních zobrazení, OnEntryHandlerChanged která implementují získání fokusu Entry .

Obslužné rutiny OnEditingDidBegin událostí přistupují k nativnímu Entry zobrazení pro příslušné platformy a vyberou veškerý text, který je v souboru Entry.OnGotFocus

Událost HandlerChanging se vyvolá před odebráním existující obslužné rutiny z ovládacího prvku pro různé platformy a před vytvořením nové obslužné rutiny pro řízení napříč platformami. Proto je obslužná rutina události tam, kde se mají odebrat odběry nativních událostí a provést další vyčištění. Objekt HandlerChangingEventArgs , který doprovází tuto událost, má OldHandler a NewHandler vlastnosti, které budou nastaveny na staré a nové obslužné rutiny v uvedeném pořadí. V tomto příkladu OnEntryHandlerChanging událost odebere odběr nativních událostí zobrazení v systémech iOS, Mac Catalyst a Windows.

Dílčí třídy

Místo podmíněné kompilace je také možné použít částečné třídy k uspořádání kódu pro přizpůsobení ovládacích prvků do složek a souborů specifických pro platformu. Pomocí tohoto přístupu je kód přizpůsobení rozdělený do částečné třídy pro různé platformy a částečné třídy specifické pro platformu:

  • Částečná třída napříč platformami obvykle definuje členy, ale neimplementuje je a je vytvořená pro všechny platformy. Tato třída by neměla být umístěna do žádné podřízené složky platformy projektu, protože by to udělalo třídu specifickou pro platformu.
  • Částečná třída specifická pro platformu obvykle implementuje členy definované v částečné třídě pro různé platformy a je vytvořená pro jednu platformu. Tato třída by měla být umístěna do podřízené složky platformy pro vaši zvolenou platformu.

Následující příklad ukazuje částečnou třídu napříč platformami:

namespace CustomizeHandlersDemo.Views;

public partial class CustomizeEntryPartialMethodsPage : ContentPage
{
    public CustomizeEntryPartialMethodsPage()
    {
        InitializeComponent();
    }

    partial void ChangedHandler(object sender, EventArgs e);
    partial void ChangingHandler(object sender, HandlerChangingEventArgs e);

    void OnEntryHandlerChanged(object sender, EventArgs e) => ChangedHandler(sender, e);
    void OnEntryHandlerChanging(object sender, HandlerChangingEventArgs e) => ChangingHandler(sender, e);
}

V tomto příkladu dva obslužné rutiny událostí volají částečné metody pojmenované ChangedHandler a ChangingHandler, jejichž podpisy jsou definovány v částečné třídě napříč platformami. Implementace částečné metody jsou pak definovány v částečných třídách specifických pro platformu, které by měly být umístěny ve správných podřízených složkách Platformy , aby se zajistilo, že se systém sestavení pokusí při sestavování pro konkrétní platformu pouze sestavit nativní kód. Například následující kód ukazuje CustomizeEntryPartialMethodsPage třídu ve složce Platforms>Windows projektu:

using Microsoft.UI.Xaml;
using Microsoft.UI.Xaml.Controls;

namespace CustomizeHandlersDemo.Views
{
    public partial class CustomizeEntryPartialMethodsPage : ContentPage
    {
        partial void ChangedHandler(object sender, EventArgs e)
        {
            Entry entry = sender as Entry;
            (entry.Handler.PlatformView as TextBox).GotFocus += OnGotFocus;
        }

        partial void ChangingHandler(object sender, HandlerChangingEventArgs e)
        {
            if (e.OldHandler != null)
            {
                (e.OldHandler.PlatformView as TextBox).GotFocus -= OnGotFocus;
            }
        }

        void OnGotFocus(object sender, RoutedEventArgs e)
        {
            var nativeView = sender as TextBox;
            nativeView.SelectAll();
        }
    }
}

Výhodou tohoto přístupu je, že podmíněná kompilace není nutná a že částečné metody nemusí být implementovány na každé platformě. Pokud na platformě není k dispozici implementace, metoda a všechna volání metody se odeberou v době kompilace. Informace o částečných metodách naleznete v části Částečné metody.

Informace o organizaci složky Platformy v projektu .NET MAUI najdete v části Částečné třídy a metody. Informace o tom, jak nakonfigurovat cílení na více platforem, abyste nemuseli umístit kód platformy do podsložek složky Platformy, najdete v tématu Konfigurace cílení na více platforem.