Aplikacje mobilne · Układy
Układy II: FlexLayout, AbsoluteLayout, ScrollView i ContentView
Grid i stosy załatwiają większość formularzy, ale nie wszystko. Czasem potrzebujesz elastycznego „zawijania” elementów jak we Flexboxie, przewijalnego długiego formularza albo powtarzalnego fragmentu interfejsu. Ta lekcja domyka przegląd układów MAUI i wyjaśnia, dlaczego nie ma tu Canvas z WPF.
- około 50 minut
- .NET MAUI · FlexLayout · ScrollView · ContentView
- INF.04.6.2
Po tej lekcji: użyć FlexLayout do elastycznych pasków i kart, ScrollView do długich formularzy, AbsoluteLayout z umiarem oraz wydzielić powtarzalny fragment interfejsu do ContentView.
Zobacz, zanim zaczniesz
Cztery ekrany, cztery problemy
Każdy ekran to podgląd z kodu XAML. Poniżej rozbijemy je na cztery etapy. W każdym najpierw krótka wiedza, potem wyzwanie, a na końcu szybkie sprawdzenie.
Zacznij od zabawy
Rozstaw przyciski jak we Flexboxie
FlexLayout działa podobnie do CSS Flexbox. Zmień JustifyContent na Start, End albo SpaceEvenly, zmień Direction na Column i obserwuj ekran. W drugim presecie dodaj Wrap="Wrap" i zmniejsz szerokość, aby elementy przeszły do nowej linii.
Najpierw przewidź, potem sprawdź: W podglądzie Flex zmieniaj JustifyContent. Sprawdź różnicę między SpaceBetween i SpaceAround przy krawędziach, nie tylko w środku.
Flex rozmieszcza elementy w osi głównej (JustifyContent) i poprzecznej (AlignItems), a Wrap pozwala im zawijać się na mniejszych ekranach. Model pomaga zobaczyć mechanizm; właściwą aplikację uruchomisz z plików poniżej.
Etap 1 z 4
FlexLayout: elastyczny rząd
FlexLayout działa podobnie do Flexboxa z CSS. Ustawiasz kierunek (Direction), rozmieszczenie wzdłuż osi (JustifyContent) i wyrównanie w poprzek (AlignItems). Z Wrap="Wrap" elementy przechodzą do nowej linii, gdy zabraknie miejsca.
2 · Ściągawka
FlexLayout: cztery właściwości
| Właściwość | Opis |
|---|---|
Direction | Row (poziomo) lub Column (pionowo). |
JustifyContent | Rozmieszczenie w osi głównej: Start, Center, End, SpaceBetween, SpaceAround, SpaceEvenly. |
AlignItems | Wyrównanie w osi poprzecznej: Start, Center, End, Stretch. |
Wrap | Z wartością Wrap elementy przechodzą do nowej linii, gdy zabraknie miejsca. Idealne do kafelków i kart. |
Wyzwanie 1 · czytanie kodu
Gdzie staną przyciski?
Wyzwanie 2 · pasek akcji
Pasek akcji z trzech przycisków
Wyzwanie 3 · zawijanie
Kafelki, które się zawijają
Sprawdź, czy zapamiętałeś
Dwa szybkie pytania
Etap 2 z 4
ScrollView: gdy treść jest dłuższa niż ekran
Telefon ma mały ekran. Formularz z kilkunastoma polami trzeba przewinąć. ScrollView robi dokładnie to, ale ma jedną zasadę: może mieć tylko jedno dziecko. Kilka elementów opakowujesz w stos.
Wyzwanie 4 · cudzy kod
Kolega zrobił formularz, który się nie uruchamia
Wyzwanie 5 · przewijany formularz
Zrób formularz przewijalny
Sprawdź, czy zapamiętałeś
Dwa szybkie pytania
Etap 3 z 4
AbsoluteLayout: element w konkretnym miejscu
AbsoluteLayout ustawia element według współrzędnych: AbsoluteLayout.LayoutBounds="x,y,szerokość,wysokość". Z LayoutFlags="All" liczby to ułamki (0–1) rozmiaru układu, więc ekran skaluje się razem z urządzeniem. Używasz go rzadko: do plakietek, nakładek i znaczników na obrazie.
Wyzwanie 6 · plakietka w rogu
Plakietka NOWE w rogu karty
Sprawdź, czy zapamiętałeś
Dwa szybkie pytania
Etap 4 z 4
ContentView: własny klocek do wielokrotnego użycia
Gdy ten sam fragment (np. wiersz ustawienia „etykieta + przełącznik”) pojawia się pięć razy, nie kopiujesz kodu. Tworzysz własny ContentView, a potem wstawiasz go jak zwykłą kontrolkę.
Wyzwanie 7 · własny klocek
Ułóż plik `WierszUstawienia.xaml`
Wyzwanie końcowe
Ekran ustawień
Sprawdź, czy zapamiętałeś
Cztery pytania z całej lekcji
9 · Ściąga
Kiedy którego użyć
| Układ | Kiedy |
|---|---|
Grid | Formularze „etykieta + pole”, panele 2–3 kolumnowe. |
Vertical/HorizontalStackLayout | Szybkie układy liniowe, paski przycisków. |
FlexLayout | Elastyczne paski akcji, kafelki, zawijanie. |
AbsoluteLayout | Rzadko: gdy trzeba „przykleić” coś w konkretnym miejscu. |
ScrollView | Długie formularze na telefonie. Koniecznie. |
ContentView | Powtarzalny fragment interfejsu. |
GraphicsView | Rysowanie i wykresy. Poza typowym zakresem INF.04. |
11 · Sprawdź się
Który układ i dlaczego?
Cztery sytuacje z ekranami.
Dla chętnych · po pierwszej stroniePracownia w Visual Studio: to samo w prawdziwym projekcie
Rozwiń dodatkowe warsztaty ↓
Wyzwania powyżej uczą w przeglądarce. Tu jest pełna instrukcja krok po kroku, jak zrobić to w Visual Studio i uruchomić na emulatorze, tak jak na egzaminie praktycznym. Otwórz, gdy będziesz gotowy do pracy z projektem.
1. Przygotuj miejsce pracy
Co dodajesz, a co podmieniasz?
Stronę dodaj przez Projekt → Dodaj → Nowy element → .NET MAUI ContentPage (XAML). Powstaje para .xaml i .xaml.cs. Dla ContentView wybierz szablon ContentView; dla modeli i serwisów zwykłą klasę. Jeśli plik już istnieje, podmień wskazaną zawartość — nie twórz drugiej klasy o tej samej nazwie.
| Plik | Rola w ćwiczeniu |
|---|---|
| PasekAkcjiPage.xaml | Wygląd strony lub kontrolki |
| FormularzDlugiPage.xaml | Wygląd strony lub kontrolki |
| AbsolutePage.xaml | Wygląd strony lub kontrolki |
| WierszUstawienia.xaml | Wygląd strony lub kontrolki |
| WierszUstawienia.xaml.cs | Logika i obsługa danych |
| UstawieniaPage.xaml | Wygląd strony lub kontrolki |
Zanim uruchomisz: trzy połączenia
x:Class="MojaAplikacja.NazwaStrony" w XAML musi zgadzać się z namespace MojaAplikacja i nazwą klasy C#. InitializeComponent() tworzy kontrolki opisane w XAML.
x:Name="PoleImie" daje kodowi C# dostęp przez PoleImie.Text. Z kolei Clicked="Zapisz_Clicked" wskazuje metodę o tej nazwie w pliku .xaml.cs. Sam napis przycisku w Text niczego nie podpina.
Gdy dodajesz XAML z obsługą zdarzeń, od razu uzupełnij też odpowiadający C#. Uruchamiaj dopiero po skończeniu oznaczonej pary plików; brakujący handler nie jest błędem środowiska.
2. Uruchom sam wygląd — jeszcze bez logiki
W świeżym projekcie zastąp MainPage.xaml poniższym ekranem. W MainPage.xaml.cs zachowaj konstruktor z InitializeComponent(); usuń szablonowy licznik i OnCounterClicked, bo nie ma ich już w XAML. Na tym etapie App i AppShell pozostają z szablonu. To pełny, tymczasowy XAML — później świadomie go podmienisz, nie dokleisz do drugiego ContentPage.
<ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="MojaAplikacja.MainPage">
<VerticalStackLayout Padding="24" Spacing="14">
<Label Text="Mój panel ustawień" FontSize="24" />
<HorizontalStackLayout Spacing="12">
<Button Text="Anuluj" />
<Button Text="Zapisz" />
</HorizontalStackLayout>
</VerticalStackLayout>
</ContentPage>
- Pierwsza próba Uruchom. Zobaczysz kontrolki, ale przyciski bez Clicked jeszcze nic nie robią. Sprawdź rozmiar i kolejność elementów. Zatrzymaj aplikację przed następnym etapem.
3. Wskaż stronę startową ćwiczenia
Po dodaniu docelowych stron podmień App.xaml.cs na poniższy. App.xaml zostaje z szablonu. Od tej chwili startuje PasekAkcjiPage, a nie wcześniejszy tymczasowy MainPage z AppShell. Uzupełnij jej pliki w kolejnych etapach, zanim ponownie uruchomisz projekt.
namespace MojaAplikacja;
public partial class App : Application
{
public App() => InitializeComponent();
protected override Window CreateWindow(IActivationState? activationState)
=> new Window(new NavigationPage(new PasekAkcjiPage()));
}
CreateWindowTworzy okno aplikacji. NavigationPage jest kontenerem zwykłych stron i daje przycisk powrotu; nie łączymy go z Shell.new PasekAkcjiPage()Tworzy instancję docelowej strony. Aby testować drugi niezależny przykład, zatrzymaj program, zmień tylko ten typ i uruchom ponownie.
4. Połącz wygląd z działaniem
Teraz zbuduj docelowy przykład. Pełne pliki poniżej zastępują swoje wcześniejsze wersje. Przeczytaj opis nad kodem i objaśnienia pod nim; potem sprawdź przepływ danych, nie tylko brak czerwonych podkreśleń.
Gdy przykład ma kilka plików zależnych od siebie, najpierw dodaj wszystkie wskazane typy, a potem uruchom całość. Ustaw breakpoint w obsłudze głównego przycisku i prześledź jedną próbę.
Budowa krok po kroku
PasekAkcjiPage.xaml
Najpierw uruchom tylko PasekAkcjiPage. Trzy paski mają podobne kontrolki, ale inny sposób rozdzielania wolnego miejsca.
Trzy warianty rozmieszczenia tych samych przycisków.
<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="MojaAplikacja.PasekAkcjiPage">
<VerticalStackLayout Spacing="14" Padding="0,16">
<Label Text="SpaceBetween" Padding="16,0" />
<FlexLayout Direction="Row" JustifyContent="SpaceBetween" AlignItems="Center" Padding="16">
<Button Text="Anuluj" WidthRequest="80" />
<Button Text="Zapisz" WidthRequest="80" />
<Button Text="Wyślij" WidthRequest="80" />
</FlexLayout>
<Label Text="SpaceAround" Padding="16,0" />
<FlexLayout Direction="Row" JustifyContent="SpaceAround" AlignItems="Center" Padding="16">
<Button Text="Anuluj" WidthRequest="80" />
<Button Text="Zapisz" WidthRequest="80" />
<Button Text="Wyślij" WidthRequest="80" />
</FlexLayout>
<Label Text="Center" Padding="16,0" />
<FlexLayout Direction="Row" JustifyContent="Center" AlignItems="Center" Padding="16">
<Button Text="Anuluj" WidthRequest="80" Margin="4" />
<Button Text="Zapisz" WidthRequest="80" Margin="4" />
</FlexLayout>
</VerticalStackLayout>
</ContentPage>
Direction="Row"Elementy w jednym rzędzie.JustifyContent="SpaceBetween"Pierwszy i ostatni element przy krawędziach, reszta równo pomiędzy nimi.JustifyContent="SpaceAround"Równe odstępy wokół każdego elementu, więc przy krawędziach jest po pół odstępu.AlignItems="Center"Wyśrodkowanie w osi poprzecznej (tu w pionie).
Budowa krok po kroku
FormularzDlugiPage.xaml
Dodaj FormularzDlugiPage. Jedynym dzieckiem ScrollView jest stos — dopiero w nim znajduje się wiele pól. Sprawdź to, zmniejszając wysokość okna.
ScrollView opakowuje jeden element potomny (tu stos z polami). Gdy formularz jest krótszy niż ekran, nic się nie przewija. Gdy jest dłuższy, użytkownik przesuwa go palcem.
<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="MojaAplikacja.FormularzDlugiPage">
<!-- Długi formularz opakowany w ScrollView, żeby dało się go przewinąć -->
<ScrollView>
<VerticalStackLayout Padding="20" Spacing="12">
<Label Text="Dane kontaktowe" FontAttributes="Bold" FontSize="22" />
<Entry Placeholder="Adres e-mail" />
<Entry Placeholder="Telefon" />
<Entry Placeholder="Ulica i numer" />
<Entry Placeholder="Miasto" />
<Entry Placeholder="Kod pocztowy" />
<Entry Placeholder="Kraj" />
<Entry Placeholder="Uwagi" />
<Button Text="Zapisz" BackgroundColor="RoyalBlue" TextColor="White" />
</VerticalStackLayout>
</ScrollView>
</ContentPage>
<ScrollView>Przyjmuje tylko jedno bezpośrednie dziecko. Kilka elementów opakuj w layout.VerticalStackLayoutw środku Zbiera wszystkie pola w jeden element, który może się przewijać.Padding="20" Spacing="12"Marginesy i odstępy działają tak samo jak w innych stosach.
Budowa krok po kroku
AbsolutePage.xaml
Dodaj AbsolutePage. Przycisk ma stałe rozmiary56×56, lecz proporcjonalną pozycję. Wymiary banera są proporcjonalne. To dwa różne użycia LayoutFlags.
AbsoluteLayout ustawia elementy w konkretnych współrzędnych albo proporcjonalnie do kontenera. Używaj go oszczędnie: sztywne pozycje trudniej utrzymać na różnych ekranach.
<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="MojaAplikacja.AbsolutePage">
<AbsoluteLayout HeightRequest="320">
<!-- Baner na górze: 20% wysokości, cała szerokość -->
<BoxView Color="#512BD4"
AbsoluteLayout.LayoutBounds="0,0,1,0.2"
AbsoluteLayout.LayoutFlags="All" />
<Label Text="Baner" TextColor="White" FontSize="22"
AbsoluteLayout.LayoutBounds="16,14,120,30" />
<!-- Przycisk przyklejony do prawego dolnego rogu -->
<Button Text="+"
AbsoluteLayout.LayoutBounds="1,1,56,56"
AbsoluteLayout.LayoutFlags="PositionProportional" />
</AbsoluteLayout>
</ContentPage>
AbsoluteLayout.LayoutBounds="x,y,szerokość,wysokość"Położenie i rozmiar elementu.LayoutFlags="All"Wszystkie liczby są ułamkami rozmiaru kontenera.0,0,1,0.2to baner na całą szerokość i 20% wysokości.LayoutFlags="PositionProportional"Tylko położenie jest proporcjonalne.1,1przykleja element do prawego dolnego rogu.
Zatrzymaj się przed kolejnym wariantem
Nie zastępuj jeszcze działającej wersji. Wykonaj tę próbę i dopiero potem przejdź do dodatku.
Dopiero teraz: drugi wariant lub rozszerzenie
To następny etap tej lekcji, nie warunek pierwszego uruchomienia. Porównaj jego rolę z działającą bazą. Jeśli brakuje czasu, wróć do niego po sprawdzeniu podstawowej wersji.
Dodatek do działającej wersji
WierszUstawienia: własny kontener
Dodaj .NET MAUI ContentView (XAML), nie ContentPage. Własny wiersz ma dwie nazwane etykiety i przełącznik.
ContentView to wydzielony fragment interfejsu, który możesz użyć w wielu miejscach, jak osobny komponent. Tutaj wiersz ustawienia: tytuł i opis po lewej, przełącznik po prawej.
<?xml version="1.0" encoding="utf-8" ?>
<ContentView xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="MojaAplikacja.WierszUstawienia">
<Grid ColumnDefinitions="*,Auto" Padding="12">
<VerticalStackLayout>
<Label x:Name="TytulLabel" FontAttributes="Bold" />
<Label x:Name="OpisLabel" TextColor="Gray" FontSize="12" />
</VerticalStackLayout>
<Switch Grid.Column="1" VerticalOptions="Center" />
</Grid>
</ContentView>
x:Name="TytulLabel"/OpisLabelC# odwołuje się do tych etykiet przez wygenerowane pola. Tekst ustawia setter zwykłej właściwości Tytul/Opis.ColumnDefinitions="*,Auto"Lewa część dostaje pozostałą szerokość, prawa mieści przełącznik.
Dodatek do działającej wersji
WierszUstawienia.xaml.cs
Podmień kod WierszUstawienia. Setter właściwości Tytul bezpośrednio ustawia Text etykiety; to jeszcze nie BindableProperty.
Dwie zwykłe właściwości C# ustawiają napisy w kontrolce. get odczytuje tekst, set przypisuje wartość value. To prosty wariant do stałych atrybutów XAML, bez wiązania tych właściwości.
namespace MojaAplikacja;
public partial class WierszUstawienia : ContentView
{
public WierszUstawienia() => InitializeComponent();
public string Tytul
{
get => TytulLabel.Text ?? "";
set => TytulLabel.Text = value;
}
public string Opis
{
get => OpisLabel.Text ?? "";
set => OpisLabel.Text = value;
}
}
set => TytulLabel.Text = valueSkrócone ciało settera. Zapis Tytul="Powiadomienia" ustawia tekst wewnętrznego Label.- Zwykła właściwość a binding Ta wersja nie obsługuje {Binding ...} ustawianego na Tytul/Opis. Wersja BindableProperty jest dodatkiem po lekcji o listach i wiązaniu (lekcja15).
Dodatek do działającej wersji
UstawieniaPage.xaml
Dodaj UstawieniaPage. local: oznacza własny typ z namespace MojaAplikacja. Cztery użycia tworzą cztery niezależne instancje wiersza.
Ten sam kontener użyty cztery razy z różnymi danymi, wewnątrz ScrollView. Każda zmiana wyglądu wiersza dotyczy wszystkich czterech naraz.
<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:local="clr-namespace:MojaAplikacja"
x:Class="MojaAplikacja.UstawieniaPage">
<ScrollView>
<VerticalStackLayout>
<local:WierszUstawienia Tytul="Powiadomienia" Opis="Pokazuj powiadomienia na ekranie blokady" />
<local:WierszUstawienia Tytul="Tryb ciemny" Opis="Ciemny motyw aplikacji" />
<local:WierszUstawienia Tytul="Lokalizacja" Opis="Zezwól na dostęp do położenia" />
<local:WierszUstawienia Tytul="Synchronizacja" Opis="Wysyłaj dane w tle" />
</VerticalStackLayout>
</ScrollView>
</ContentPage>
xmlns:local="clr-namespace:MojaAplikacja"Przestrzeń nazw, dzięki której XAML zna Twój kontener.<local:WierszUstawienia Tytul="…" />Użycie własnego kontenera jak zwykłej kontrolki.
Plik .xaml.cs też musi istnieć
Szablon strony lub ContentView generuje poniższe klasy. Nie dodawaj ich drugi raz, jeśli Visual Studio już je utworzyło. W każdej parze musi pozostać InitializeComponent().
PasekAkcjiPage — minimalny kod za widokiem
namespace MojaAplikacja;
public partial class PasekAkcjiPage : ContentPage
{
public PasekAkcjiPage() => InitializeComponent();
}
partialDruga część klasy powstaje z XAML. Nie twórz ręcznie pól kontrolek ani drugiej metody InitializeComponent.
FormularzDlugiPage — minimalny kod za widokiem
namespace MojaAplikacja;
public partial class FormularzDlugiPage : ContentPage
{
public FormularzDlugiPage() => InitializeComponent();
}
partialDruga część klasy powstaje z XAML. Nie twórz ręcznie pól kontrolek ani drugiej metody InitializeComponent.
AbsolutePage — minimalny kod za widokiem
namespace MojaAplikacja;
public partial class AbsolutePage : ContentPage
{
public AbsolutePage() => InitializeComponent();
}
partialDruga część klasy powstaje z XAML. Nie twórz ręcznie pól kontrolek ani drugiej metody InitializeComponent.
UstawieniaPage — minimalny kod za widokiem
namespace MojaAplikacja;
public partial class UstawieniaPage : ContentPage
{
public UstawieniaPage() => InitializeComponent();
}
partialDruga część klasy powstaje z XAML. Nie twórz ręcznie pól kontrolek ani drugiej metody InitializeComponent.
5. Odbiór: czy naprawdę działa?
Wykonaj próby w swojej aplikacji, nie tylko w modelu na stronie. Zaznaczaj dopiero po sprawdzeniu wyniku. Funkcje urządzenia wymagają testu na właściwej platformie.
10 · Czego unikać
Cztery błędy z układami
Wiele dzieci w ScrollView
<ScrollView>
<Entry />
<Entry />
</ScrollView>Błąd: ScrollView akceptuje tylko jedno dziecko.
<ScrollView>
<VerticalStackLayout>
<Entry />
<Entry />
</VerticalStackLayout>
</ScrollView>Kilka elementów opakuj w jeden layout.
Nadużywanie AbsoluteLayout
AbsoluteLayout.LayoutBounds="240,610,100,40" // piksele na sztywnoWygląda dobrze na jednym ekranie, a na innym elementy wychodzą poza niego.
Grid albo FlexLayout (lub LayoutFlags z ułamkami)W większości przypadków Grid lub Flex są odporniejsze na zmianę rozmiaru.
Szukanie Canvas
Szukam odpowiednika Canvas z WPF do ułożenia przycisków.W MAUI nie ma takiej kontrolki do układania.
Układ: Grid, stosy, Flex. Rysowanie: GraphicsView.To dwie różne potrzeby: układ i rysowanie.
Brak ScrollView w długim formularzu
Formularz z dziesięcioma polami bez przewijaniaNa małym telefonie dolne pola i przycisk są ucięte. Na dużym monitorze podczas testów tego nie widać.
Opakuj stos pól w ScrollView i sprawdź na emulatorze telefonuZawartość, która nie mieści się na ekranie, bez przewijania jest niedostępna.
Ćwiczenie z pomocą · samodzielna praca
6. Mała zmiana, którą zrobisz samodzielnie
Dodaj piąty wiersz ustawień: Dźwięki, z własnym opisem.
Dodaj piąty wiersz ustawień: Dźwięki, z własnym opisem. Dotychczasowe działanie ma pozostać poprawne.
? Potrzebujesz pomocy? Rozwiązuj krok po kroku.
Krok 1 — pokaż podpowiedź
Dopisz kolejne local:WierszUstawienia wewnątrz istniejącego stosu.
Krok 2 — pokaż podpowiedź
Ustaw Tytul i Opis jako zwykłe napisy; tej wersji nie zasilamy jeszcze wiązaniem Binding.
Krok 3 — pokaż podpowiedź
Sprawdź przewijanie po zmniejszeniu okna, nie zwiększaj HeightRequest całej strony.
Otwórz tylko tyle podpowiedzi, ile potrzebujesz. Po każdym kroku wróć do zadania i sprawdź wynik.
Podsumowanie
Co warto zapamiętać
- FlexLayout:
Direction,JustifyContent,AlignItems,Wrap. Elastyczne paski i karty. - ScrollView ma jedno dziecko i jest obowiązkowy przy długich formularzach na telefonie.
- AbsoluteLayout używaj oszczędnie.
LayoutBoundsiLayoutFlagspozwalają na pozycje proporcjonalne. - ContentView wydziela powtarzalny fragment interfejsu, ze zwykłymi właściwościami C#; BindableProperty poznasz po wiązaniu danych.
- W MAUI nie ma
Canvas. Do rysowania jestGraphicsView, do układania Grid, stosy i Flex.
Dalej na swoim koncie
Rozgrzewki, quiz i zadania są w biurku ucznia.
Teoria jest otwarta dla wszystkich. Żeby rozwiązywać zadania, zapisywać szkice i widzieć swój postęp, zaloguj się.
Zaloguj się →