Zrozumiesz, po co rozdzielać widok (UI) od logiki i jak to zrobić w praktyce na prostym przykładzie: formularz z Imię + Nazwisko → przycisk Wyślij → etykieta z wynikiem.
Dlaczego to robimy?
- Porządek: w
MainPage.xaml.cszostaje tylko obsługa przycisku i odczyt/zapis do kontrolek. Obliczenia/zasady idą do osobnej klasy. - Łatwiejsze testowanie: logikę można sprawdzić bez uruchamiania aplikacji.
- Rozszerzalność: dodajesz kolejne funkcje w klasie logiki, UI się nie sypie.
Co oddzielamy?
- UI (widok) – układ i wygląd kontrolek:
MainPage.xaml. - Łączenie z UI – minimalny kod, który reaguje na kliknięcia i przekazuje dane:
MainPage.xaml.cs. - Logika – czysta klasa z metodami, bez wiedzy o przyciskach/Entry/Label:
Logika/Formater.cs.
Jak to się łączy (mechanika)
x:Namew XAML nadaje kontrolce nazwę (np.PoleImie). Dzięki temu ta kontrolka jest widoczna wMainPage.xaml.csjako pole.Clicked="PrzyciskWyslij_Click"podłącza zdarzenie przycisku do metody wMainPage.xaml.cs.InitializeComponent()w konstruktorzeMainPage„wczytuje” XAML i tworzy kontrolki.using MojaApp.Logika;pozwala użyć klasy z osobnego pliku/folderu.- Tworzymy obiekt logiki (
new Formater()) i wołamy jego metody.
Drzewo aplikacji
MojaApp
┣ App.xaml
┣ App.xaml.cs
┣ MainPage.xaml ← UI (widok)
┣ MainPage.xaml.cs ← połączenie z UI (eventy, odczyt/zapis)
┣ Logika
┃ ┗ Formater.cs ← czysta logika
┗ ... (inne pliki)
Folder
Logikanie jest obowiązkowy, ale pomaga utrzymać porządek. Możesz też umieścićFormater.csobokMainPage.xaml.cs.
Krok po kroku w Visual Studio (PL interfejs)
- Dodaj widok: projekt MAUI już ma
MainPage.xaml. - Dodaj folder: PPM na projekt → Dodaj → Nowy folder →
Logika. - Dodaj klasę logiki: PPM na
Logika→ Dodaj → Klasa… →Formater.cs. - Połącz przycisk z metodą: w XAML ustaw
Clicked="PrzyciskWyslij_Click", a wMainPage.xaml.csdopisz metodęPrzyciskWyslij_Click.
Pliki i pełne kody (z objaśnieniami linia po linii)
1) MainPage.xaml (UI)
<ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="MojaApp.MainPage"
Title="Formularz">
<VerticalStackLayout Padding="20" Spacing="12">
<Entry x:Name="PoleImie" Placeholder="Imię" />
<Entry x:Name="PoleNazwisko" Placeholder="Nazwisko" />
<Button Text="Wyślij" Clicked="PrzyciskWyslij_Click" />
<Label x:Name="WynikLabel" Text="Tu pojawi się wynik" FontAttributes="Bold" />
</VerticalStackLayout>
</ContentPage>
Wyjaśnienia:
<ContentPage ...>– strona widoku.xmlns="...maui"– standardowe „adresy” opisujące język XAML dla MAUI.xmlns:x=".../xaml"– dodatkowe funkcje XAML (np.x:Name).x:Class="MojaApp.MainPage"– pełna nazwa klasy, która łączy ten XAML z plikiemMainPage.xaml.cs.Title="Formularz"– tytuł strony.<VerticalStackLayout ...>– układ, który ustawia elementy pionowo.Padding="20"– wewnętrzny margines kontenera (odstęp od krawędzi).Spacing="12"– odstęp między elementami wewnątrz.<Entry x:Name="PoleImie" .../>– pole tekstowe;x:Namenadaje mu nazwę widoczną w C#.<Entry x:Name="PoleNazwisko" .../>– drugie pole.<Button Text="Wyślij" Clicked="PrzyciskWyslij_Click"/>– przycisk;Clickedwskazuje metodę w C#, która wykona się po kliknięciu.<Label x:Name="WynikLabel" .../>– etykieta na wynik; też max:Name, więc można zmieniaćTextz C#.
2) MainPage.xaml.cs (połączenie z UI)
using MojaApp.Logika; // pozwala odwołać się do klasy Formater z folderu Logika
namespace MojaApp;
public partial class MainPage : ContentPage
{
private readonly Formater _formater = new(); // tworzymy obiekt logiki raz i używamy go w zdarzeniach
public MainPage()
{
InitializeComponent(); // wczytuje XAML, tworzy kontrolki i łączy je z polami (np. PoleImie)
}
private void PrzyciskWyslij_Click(object sender, EventArgs e)
{
// 1) Odczyt tekstu z pól Entry
string imie = PoleImie.Text; // to jest string (ciąg znaków) z kontrolki Entry
string nazwisko = PoleNazwisko.Text;
// 2) Logika w osobnej klasie – przekazujemy dane i dostajemy wynik
string wynik = _formater.PolaczImieNazwisko(imie, nazwisko);
// 3) Wyświetlenie wyniku w etykiecie
WynikLabel.Text = wynik;
}
}
Wyjaśnienia:
using MojaApp.Logika;– import przestrzeni nazw, gdzie jest klasaFormater.namespace MojaApp;– przestrzeń nazw (żeby klasy miały unikalne „adresy”).public partial class MainPage : ContentPage–partialoznacza, że definicja klasy jest podzielona między XAML i ten plik C#.Formater _formater = new();– tworzymy obiekt logiki do użycia.InitializeComponent();– najważniejsza linia łącząca XAML z C#: tworzy kontrolki, nadaje im referencje (np.PoleImie).PrzyciskWyslij_Click(...)– metoda wywoływana po kliknięciu (bo wskazaliśmy ją w XAML wClicked="...").PoleImie.Text/PoleNazwisko.Text– odczyt tekstu wpisanego przez użytkownika._formater.PolaczImieNazwisko(...)– przekazujemy dane do logiki i dostajemy gotowy wynik.WynikLabel.Text = wynik;– aktualizujemy UI.
3) Logika/Formater.cs (czysta logika)
namespace MojaApp.Logika;
public class Formater
{
public string PolaczImieNazwisko(string imie, string nazwisko)
{
if (string.IsNullOrWhiteSpace(imie) && string.IsNullOrWhiteSpace(nazwisko))
return "Proszę podać imię i nazwisko.";
if (string.IsNullOrWhiteSpace(imie))
return $"Nazwisko: {nazwisko}";
if (string.IsNullOrWhiteSpace(nazwisko))
return $"Imię: {imie}";
return $"{imie} {nazwisko}";
}
}
Wyjaśnienia:
namespace MojaApp.Logika;– ta klasa żyje w przestrzeni nazwMojaApp.Logika.public class Formater– zwykła klasa, nie wie nic o przyciskach, Entry czy Label.PolaczImieNazwisko(...)– metoda przyjmuje dwa napisy i zwraca jeden wynik.string.IsNullOrWhiteSpace(...)– sprawdza, czy tekst jest pusty lub tylko ze spacjami. Dzięki temu ładnie obsługujemy brak danych.- Zwracane komunikaty są już „gotowe do wyświetlenia” – UI nie musi nic liczyć ani formować.
Co warto zapamiętać
XAML– opisuje co i jak wygląda.code-behind (xaml.cs)– zbiera dane z UI i wywołuje logikę.osobny plik klasy– robi przeliczenia/zasady i zwraca gotowy wynik.- Spina to wszystko:
x:Name,Clicked="Metoda",InitializeComponent(),using <TwojaPrzestrzen>,new Klasa()i wywołanie metod.
Ćwiczenie:
- Zmień logikę tak, aby wynik był w formacie:
NAZWISKO, Imię(np.Kowalski, Jan). - Dodaj walidację: jeśli imię jest krótsze niż 2 znaki, pokaż komunikat:
Imię jest za krótkie. - Dodaj drugi przycisk „Wyczyść”, który czyści oba pola i etykietę.
Podsumowanie
Rozdzielenie logiki od UI to fundament większych aplikacji. Dzięki temu:
- łatwiej utrzymasz porządek,
- szybciej znajdziesz błędy,
- łatwiej przygotujesz się do testów jednostkowych (następny temat).

