Dostosowywanie kontrolek za pomocą programów obsługi
Programy obsługi można dostosować w celu rozszerzenia wyglądu i zachowania kontrolki międzyplatformowej poza dostosowywanie, które jest możliwe za pośrednictwem interfejsu API kontrolki. To dostosowanie, które modyfikuje widoki natywne dla kontrolki międzyplatformowej, jest osiągane przez zmodyfikowanie mapera dla programu obsługi przy użyciu jednej z następujących metod:
- PrependToMapping, który modyfikuje maper programu obsługi przed zastosowaniem mapowań kontrolek .NET MAUI.
- ModifyMapping, który modyfikuje istniejące mapowanie.
- AppendToMapping, który modyfikuje maper programu obsługi po zastosowaniu mapowań kontrolek .NET MAUI.
Każda z tych metod ma identyczny podpis, który wymaga dwóch argumentów:
string
Klucz oparty na protokole . Podczas modyfikowania jednego z mapowań dostarczonych przez program .NET MAUI należy określić klucz używany przez program .NET MAUI. Wartości kluczy używane przez mapowania kontrolek MAUI platformy .NET są oparte na nazwach interfejsów i właściwości, na przykładnameof(IEntry.IsPassword)
. Interfejsy i ich właściwości, które abstrakują poszczególne kontrolki międzyplatformowe, można znaleźć tutaj. Jest to format klucza, który powinien być używany, jeśli chcesz, aby dostosowanie programu obsługi było uruchamiane za każdym razem, gdy zmienia się właściwość. W przeciwnym razie klucz może być dowolną wartością, która nie musi odpowiadać nazwie właściwości uwidocznionej przez typ. Można na przykładMyCustomization
określić jako klucz, z dowolną modyfikacją widoku natywnego wykonywaną jako dostosowanie. Jednak konsekwencją tego formatu klucza jest to, że dostosowanie programu obsługi zostanie uruchomione tylko wtedy, gdy maper programu obsługi zostanie po raz pierwszy zmodyfikowany.- Element Action reprezentujący metodę, która wykonuje dostosowywanie programu obsługi. Parametr Action określa dwa argumenty:
handler
Argument, który udostępnia wystąpienie programu obsługi, który jest dostosowywany.view
Argument, który udostępnia wystąpienie kontrolki międzyplatformowej, którą implementuje program obsługi.
Ważne
Dostosowania procedury obsługi są globalne i nie są ograniczone do określonego wystąpienia kontrolki. Dostosowywanie programu obsługi może nastąpić w dowolnym miejscu w aplikacji. Po dostosowaniu procedury obsługi ma ona wpływ na wszystkie kontrolki tego typu, wszędzie w aplikacji.
Każda klasa obsługi uwidacznia widok macierzysty dla kontrolki międzyplatformowej za pośrednictwem jej PlatformView właściwości. Dostęp do tej właściwości można uzyskać, aby ustawić właściwości widoku natywnego, wywołać metody widoku natywnego i zasubskrybować zdarzenia widoku natywnego. Ponadto kontrolka międzyplatformowa zaimplementowana przez program obsługi jest uwidaczniona za pośrednictwem jego VirtualView właściwości.
Programy obsługi można dostosować na platformę przy użyciu kompilacji warunkowej w kodzie wielokierunkowym opartym na platformie. Alternatywnie można użyć klas częściowych do organizowania kodu w foldery i pliki specyficzne dla platformy. Aby uzyskać więcej informacji na temat kompilacji warunkowej, zobacz Kompilacja warunkowa.
Dostosowywanie kontrolki
Widok MAUI Entry platformy .NET to jednowierszowa kontrolka wprowadzania tekstu, która implementuje IEntry interfejs. Widok EntryHandler jest mapowy Entry na następujące widoki natywne dla każdej platformy:
- Katalizator systemu iOS/Mac:
UITextField
- Android:
AppCompatEditText
- Windows:
TextBox
Na poniższych diagramach pokazano, jak Entry widok jest mapowany na widoki natywne za pośrednictwem elementu EntryHandler:
Maper Entry właściwości w EntryHandler klasie mapuje właściwości kontrolek międzyplatformowych na interfejs API widoku natywnego. Gwarantuje to, że po ustawieniu właściwości na Entryobiekcie podstawowy widok macierzysty jest aktualizowany zgodnie z potrzebami.
Maper właściwości można zmodyfikować w celu dostosowania Entry na każdej platformie:
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
});
}
}
W tym przykładzie Entry dostosowanie odbywa się w klasie strony. W związku z tym wszystkie Entry kontrolki w systemach Android, iOS i Windows zostaną dostosowane po utworzeniu wystąpienia.CustomizeEntryPage
Dostosowywanie jest wykonywane przez uzyskanie dostępu do właściwości procedur PlatformView obsługi, która zapewnia dostęp do widoku natywnego mapowania na kontrolkę międzyplatformową na każdej platformie. Następnie kod natywny dostosowuje procedurę obsługi, zaznaczając cały tekst w Entry obiekcie, gdy zyskuje fokus.
Aby uzyskać więcej informacji na temat maperów, zobacz Mappers (Mapery).
Dostosowywanie określonego wystąpienia kontrolki
Programy obsługi są globalne, a dostosowywanie procedury obsługi dla kontrolki spowoduje dostosowanie wszystkich kontrolek tego samego typu w aplikacji. Jednak programy obsługi dla określonych wystąpień kontrolek można dostosować przez podklasę kontrolki, a następnie zmodyfikować program obsługi dla podstawowego typu kontrolki tylko wtedy, gdy kontrolka jest typu podklasy. Aby na przykład dostosować określoną Entry kontrolkę na stronie zawierającej wiele Entry kontrolek, należy najpierw podklasować kontrolkę Entry :
namespace CustomizeHandlersDemo.Controls
{
internal class MyEntry : Entry
{
}
}
Następnie można dostosować element , za pomocą mapatora EntryHandler
właściwości, aby wykonać żądaną modyfikację tylko do MyEntry
wystąpień:
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
}
});
Jeśli dostosowanie programu obsługi zostanie wykonane w klasie App
, wszystkie MyEntry
wystąpienia w aplikacji zostaną dostosowane zgodnie z modyfikacją programu obsługi.
Dostosowywanie kontrolki przy użyciu cyklu życia programu obsługi
Wszystkie procedury obsługi oparte na programie .NET MAUI steruje obsługą HandlerChanging i HandlerChanged zdarzeniami. Zdarzenie HandlerChanged jest zgłaszane, gdy widok natywny, który implementuje kontrolkę międzyplatformową, jest dostępny i inicjowany. Zdarzenie HandlerChanging jest zgłaszane, gdy program obsługi kontrolki ma zostać usunięty z kontrolki międzyplatformowej. Aby uzyskać więcej informacji na temat zdarzeń cyklu życia programu obsługi, zobacz Cykl życia programu obsługi.
Cykl życia programu obsługi może służyć do dostosowywania programu obsługi. Aby na przykład zasubskrybować i anulować subskrypcję, zdarzenia widoku natywnego należy zarejestrować programy obsługi zdarzeń dla HandlerChanged zdarzeń i HandlerChanging na dostosowanej kontrolce międzyplatformowej:
<Entry HandlerChanged="OnEntryHandlerChanged"
HandlerChanging="OnEntryHandlerChanging" />
Programy obsługi można dostosować na platformę przy użyciu kompilacji warunkowej lub za pomocą klas częściowych do organizowania kodu w foldery i pliki specyficzne dla platformy. Każde podejście zostanie omówione z kolei przez dostosowanie Entry elementu tak, aby cały jego tekst został wybrany, gdy zyska fokus.
Kompilacja warunkowa
Plik za kodem zawierający programy obsługi zdarzeń dla HandlerChanged zdarzeń i HandlerChanging jest pokazany w poniższym przykładzie, który korzysta z kompilacji warunkowej:
#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
}
Zdarzenie HandlerChanged jest wywoływane po utworzeniu i zainicjowaniu widoku natywnego, który implementuje kontrolkę międzyplatformową. W związku z tym program obsługi zdarzeń to miejsce, w którym powinny być wykonywane subskrypcje zdarzeń natywnych. Wymaga to rzutowania PlatformView właściwości programu obsługi na typ lub typ podstawowy widoku natywnego, aby można było uzyskać dostęp do zdarzeń natywnych. W tym przykładzie w systemach iOS, Mac Catalyst i Windows OnEntryHandlerChanged
zdarzenie subskrybuje zdarzenia widoku natywnego, które są zgłaszane, gdy widoki natywne implementujące Entry fokus zysku.
Programy OnEditingDidBegin
obsługi zdarzeń i OnGotFocus
uzyskują dostęp do widoku natywnego dla odpowiednich Entry platform i wybierają cały tekst w obiekcie Entry.
Zdarzenie HandlerChanging jest wywoływane przed usunięciem istniejącego programu obsługi z kontrolki międzyplatformowej i przed utworzeniem nowej procedury obsługi dla kontrolki międzyplatformowej. W związku z tym jego program obsługi zdarzeń to miejsce, w którym należy usunąć subskrypcje zdarzeń natywnych, a inne oczyszczanie powinno zostać wykonane. Obiekt HandlerChangingEventArgs , który towarzyszy temu zdarzeniu, ma OldHandler właściwości i NewHandler , które zostaną ustawione odpowiednio na stare i nowe procedury obsługi. W tym przykładzie OnEntryHandlerChanging
zdarzenie usuwa subskrypcję zdarzeń widoku natywnego w systemach iOS, Mac Catalyst i Windows.
Klasy częściowe
Zamiast korzystać z kompilacji warunkowej, można również używać klas częściowych do organizowania kodu dostosowywania kontrolek w folderach i plikach specyficznych dla platformy. Dzięki temu podejściu kod dostosowywania jest oddzielony od klasy częściowej międzyplatformowej i częściowej klasy specyficznej dla platformy:
- Klasa częściowa międzyplatformowa zwykle definiuje elementy członkowskie, ale ich nie implementuje i jest tworzona dla wszystkich platform. Ta klasa nie powinna być umieszczana w żadnym folderze podrzędnym Platformy projektu, ponieważ uczyniłoby to klasą specyficzną dla platformy.
- Klasa częściowa specyficzna dla platformy zwykle implementuje składowe zdefiniowane w klasie częściowej międzyplatformowej i jest tworzona dla jednej platformy. Ta klasa powinna zostać umieszczona w folderze podrzędnym folderu Platformy dla wybranej platformy.
W poniższym przykładzie przedstawiono międzyplatformową klasę częściową:
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);
}
W tym przykładzie dwa programy obsługi zdarzeń nazywają metody częściowe o nazwie ChangedHandler
i ChangingHandler
, których podpisy są zdefiniowane w klasie częściowej międzyplatformowej. Implementacje metody częściowej są następnie definiowane w klasach częściowych specyficznych dla platformy, które powinny zostać umieszczone w odpowiednich folderach podrzędnych Platformy , aby upewnić się, że system kompilacji próbuje skompilować kod natywny tylko podczas kompilowania dla określonej platformy. Na przykład poniższy kod przedstawia klasę CustomizeEntryPartialMethodsPage
w folderze Platformy>systemu 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();
}
}
}
Zaletą tego podejścia jest to, że kompilacja warunkowa nie jest wymagana i że metody częściowe nie muszą być implementowane na każdej platformie. Jeśli implementacja nie jest udostępniana na platformie, metoda i wszystkie wywołania metody zostaną usunięte w czasie kompilacji. Aby uzyskać informacje na temat metod częściowych, zobacz Metody częściowe.
Aby uzyskać informacje o organizacji folderu Platformy w projekcie .NET MAUI, zobacz Częściowe klasy i metody. Aby uzyskać informacje o sposobie konfigurowania wielowersyjności, aby nie trzeba było umieszczać kodu platformy w podfolderach folderu Platformy , zobacz Konfigurowanie wielowersyjności.