Megjegyzés
Az oldalhoz való hozzáféréshez engedély szükséges. Megpróbálhat bejelentkezni vagy módosítani a címtárat.
Az oldalhoz való hozzáféréshez engedély szükséges. Megpróbálhatja módosítani a címtárat.
A kezelők testre szabhatók, hogy a platformokon átívelő vezérlők megjelenését és viselkedését az API által lehetséges testreszabáson túl is fokozzák. Ez a testreszabás, amely módosítja a platformfüggetlen vezérlőelem natív nézeteit, úgy érhető el, hogy módosítja egy kezelő leképezését az alábbi módszerek egyikével:
- PrependToMapping, amely módosítja a kezelőhöz tartozó leképezőt, mielőtt a .NET MAUI vezérlők leképezése megtörténik.
- ModifyMapping, amely módosítja a meglévő leképezést.
- AppendToMapping, amely módosítja egy kezelő leképezését a .NET MAUI-vezérlőleképezések alkalmazása után.
Mindegyik metódus azonos aláírást használ, amely két argumentumot igényel:
- Egy
string
-alapú kulcs. A .NET MAUI által biztosított leképezések egyikének módosításakor meg kell adni a .NET MAUI által használt kulcsot. A .NET MAUI vezérlőleképezések által használt fő értékek példáulnameof(IEntry.IsPassword)
felület- és tulajdonságneveken alapulnak. A dotnet/maui adattárban megtalálhatja azokat a felületeket, amelyek minden platformfüggetlen vezérlőt elvonnak. Ezt a kulcsformátumot kell használni, ha azt szeretné, hogy a kezelő testreszabása minden alkalommal fusson, amikor egy tulajdonság megváltozik. Ellenkező esetben a kulcs tetszőleges érték lehet, amely nem felel meg egy típus által közzétett tulajdonság nevének. Megadható példáulMyCustomization
kulcsként, és a testreszabás során bármilyen natív nézetmódosítást végrehajthat. Ennek a kulcsformátumnak azonban az a következménye, hogy a kezelő testreszabása csak a kezelő mapperjének első módosításakor lesz futtatva. - Az Action a módszer, amely végrehajtja a kezelő testreszabását. A Action két argumentumot adja meg:
- Egy
handler
argumentum, amely a testre szabandó kezelő egy példányát adja meg. - Egy
view
argumentum, amely a kezelő által implementálható platformfüggetlen vezérlőelem egy példányát biztosítja.
- Egy
Fontos
A kezelő testreszabásai globálisak, és nem tartoznak egy adott vezérlőpéldány hatókörébe. A kezelő testreszabása az alkalmazásban bárhol megtörténhet. Miután testre szabta a kezelőt, az az alkalmazás minden részén hatással van az ilyen típusú vezérlőkre.
Minden kezelőosztály a PlatformView tulajdonságán keresztül teszi elérhetővé a platformfüggetlen vezérlőelem natív nézetét. Ez a tulajdonság elérhető natív nézettulajdonságok beállításához, natív nézetmetszetek meghívásához és natív nézetesemények előfizetéséhez. Emellett a kezelő által implementált platformfüggetlen vezérlés a VirtualView tulajdonságán keresztül érhető el.
A kezelők platformonként testre szabhatók feltételes fordítás használatával, hogy több platformra célozzák a kódot. Másik lehetőségként részleges osztályokkal platformspecifikus mappákba és fájlokba rendezheti a kódot. A feltételes fordítással kapcsolatos további információkért lásd a feltételes fordítást.
Vezérlőelem testreszabása
A .NET MAUI Entry nézet egy egysoros szövegbeviteli vezérlő, amely implementálja a IEntry felületet. A EntryHandler leképezi a Entry nézetet az alábbi saját platformnézetekre:
-
iOS/Mac Catalyst:
UITextField
-
Android:
AppCompatEditText
-
Windows:
TextBox
-
iOS/Mac Catalyst:
UITextField
-
Android:
MauiAppCompatEditText
-
Windows:
TextBox
Az alábbi diagramok azt mutatják be, hogy a Entry nézet hogyan van megfeleltetve a natív nézeteihez a EntryHandlerkövetkezőn keresztül:
Az Entry tulajdonság-leképezője, a EntryHandler osztályban, leképezi a platformfüggetlen vezérlő tulajdonságait a natív nézet API-hoz. Ez biztosítja, hogy amikor egy tulajdonság be van állítva a Entry elemre, a mögöttes natív nézet szükség szerint frissül.
A tulajdonság-leképező az egyes platformokon testre szabható Entry :
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
});
}
}
Ebben a példában a Entry testreszabás egy laposztályban történik. Ezért az Android, az iOS és a Windows összes Entry vezérlője testre lesz szabva a CustomizeEntryPage
példány létrehozása után. A testreszabás a kezelők PlatformView tulajdonságának elérésével történik, amely hozzáférést biztosít az egyes platformok platformfüggetlen vezérlőjére leképező natív nézethez. A natív kód ezután testre szabja a kezelőt úgy, hogy kijelöli az összes szöveget a Entry fókuszba kerüléskor.
További információ a mapperekről: Mappers.
Adott vezérlőpéldány testreszabása
A kezelők globálisak, és ha egy vezérlőhöz testre szab egy kezelőt, az az alkalmazás minden azonos típusú vezérlőjének testreszabását eredményezi. Az egyes vezérlőpéldányok kezelői azonban testre szabhatók a vezérlő alosztályozásával, majd az alap vezérlőelemtípus kezelőjének módosításával, csak akkor, ha a vezérlő alosztályozott típusú. Ha például egy adott Entry vezérlőelemet szeretne testre szabni egy több Entry vezérlőt tartalmazó lapon, először a vezérlőelemet kell alásorolnia Entry :
namespace CustomizeHandlersDemo.Controls
{
internal class MyEntry : Entry
{
}
}
Ezután testre szabhatja a EntryHandler
tulajdonság-leképezőn keresztül, hogy a kívánt módosítást csak a MyEntry
példányokra végezze el.
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
}
});
Ha a kezelő testreszabása az ön App
osztályában történik, az alkalmazás bármely MyEntry
példánya igazodik a kezelő módosításához.
Vezérlő testreszabása a kezelő életciklusának használatával
Minden kezelőalapú .NET MAUI-vezérlő támogatja HandlerChanging és HandlerChanged eseményeket. Az HandlerChanged esemény akkor jön elő, ha a platformfüggetlen vezérlőt megvalósító natív nézet elérhető és inicializálható. Az HandlerChanging esemény akkor lép fel, amikor a vezérlő kezelője hamarosan el lesz távolítva a platformfüggetlen vezérlőből. A kezelő életciklus-eseményeiről további információt a Kezelő életciklusa című témakörben talál.
A kezelő életciklusa felhasználható a kezelő egyedi beállításainak végrehajtására. Ha például natív nézet eseményekre szeretne előfizetni és leiratkozni, regisztrálnia kell az eseménykezelőket a HandlerChanged és HandlerChanging eseményekhez a testre szabott platformfüggetlen vezérlőn.
<Entry HandlerChanged="OnEntryHandlerChanged"
HandlerChanging="OnEntryHandlerChanging" />
A kezelők platformonként testre szabhatók feltételes fordítással, vagy részleges osztályok használatával a kód platformspecifikus mappákba és fájlokba való rendszerezéséhez. Minden megközelítést sorra tárgyalunk, egy Entry testreszabásával, úgy, hogy a fókuszba kerülésekor az összes szöveg ki legyen jelölve.
Feltételes kompilálás
A következő példa a kód mögötti fájlt mutatja, amely feltételes fordítást használ és tartalmazza az eseményekhez tartozó HandlerChanged és HandlerChanging eseménykezelőket.
#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
}
#if ANDROID
using Microsoft.Maui.Platform;
#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 MauiAppCompatEditText).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
}
Az HandlerChanged esemény a platformfüggetlen vezérlőt megvalósító natív nézet létrehozása és inicializálása után jön létre. Ezért az eseménykezelőben natív esemény-előfizetéseket kell végrehajtani. Ehhez meg kell adni a PlatformView kezelő tulajdonságát a natív nézet típusának vagy alaptípusának, hogy a natív események elérhetők legyenek. Ebben a példában iOS, Mac Catalyst és Windows rendszeren az OnEntryHandlerChanged
esemény feliratkozik a natív nézet eseményeire, amelyek akkor jelentkeznek, amikor a Entry-t megvalósító natív nézetek kapnak fókuszt.
A OnEditingDidBegin
és OnGotFocus
eseménykezelők hozzáférnek a natív nézethez a Entry saját platformjukon, és kiválasztják a Entry-ban található összes szöveget.
Az HandlerChanging eseményt a rendszer azelőtt hozza létre, hogy a meglévő kezelő el lesz távolítva a platformfüggetlen vezérlőből, és mielőtt létrejön a platformfüggetlen vezérlő új kezelője. Ezért az eseménykezelőben el kell távolítani a natív esemény-előfizetéseket, és más tisztítást kell végezni. Az HandlerChangingEventArgs objektum, amely kíséri ezt az eseményt, OldHandler és NewHandler tulajdonságokkal rendelkezik, amelyek a régi és az új kezelőkre lesznek beállítva. Ebben a példában az OnEntryHandlerChanging
esemény eltávolítja az előfizetést a natív megtekintési eseményekre iOS, Mac Catalyst és Windows rendszeren.
Részleges osztályok
A feltételes fordítás helyett részleges osztályok használatával is rendszerezheti a vezérlő testreszabási kódját platformspecifikus mappákba és fájlokba. Ezzel a módszerrel a testreszabási kód egy platformfüggetlen részleges osztályra és egy platformspecifikus részleges osztályra van elválasztva:
- A platformfüggetlen részleges osztály általában meghatározza a tagokat, de nem implementálja őket, és minden platformhoz készült. Ezt az osztályt nem szabad a projekt egyik Platform gyermekmappájába sem helyezni, mert ez platformspecifikus osztálysá tenné.
- A platformspecifikus részleges osztály általában a platformfüggetlen részleges osztályban meghatározott tagokat implementálja, és egyetlen platformhoz készült. Ezt az osztályt a választott platform Platformok mappájának gyermekmappájába kell helyezni.
Az alábbi példa egy platformfüggetlen részleges osztályt mutat be:
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);
}
Ebben a példában a két eseménykezelő részleges metódusokat hív meg ChangedHandler
, amelyek ChangingHandler
aláírása a platformfüggetlen részleges osztályban van definiálva. A részleges metódus implementációit ezután a platformspecifikus részleges osztályok határozzák meg, amelyeket a megfelelő platformok gyermekmappáiba kell helyezni, hogy a buildelési rendszer csak natív kódot hozzon létre az adott platform létrehozásakor. A következő kód például a CustomizeEntryPartialMethodsPage
projekt Platform Windows> mappájában lévő osztályt mutatja be:
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();
}
}
}
Ennek a megközelítésnek az az előnye, hogy nincs szükség feltételes fordításra, és hogy a részleges metódusokat nem kell implementálnunk az egyes platformokon. Ha egy implementáció nem érhető el egy platformon, akkor a metódus és a metódushoz intézett összes hívás fordításkor törlődik. A részleges metódusokról további információt a Részleges metódusok című témakörben talál.
A Platformok mappa .NET MAUI-projektben való szervezéséről további információt a Részleges osztályok és metódusok című témakörben talál. Ha tudni szeretné, hogyan konfigurálhat többhelyes célzást, hogy ne kelljen platformkódot helyeznie a Platformok mappa almappáiba, olvassa el a Többhelyes célzás konfigurálása című témakört.