wykład 1
Transkrypt
wykład 1
Programowanie obiektowe i zdarzeniowe wykład 1 – Wprowadzenie do programowania zdarzeniowego Wymagania wstępne: Znajomość podstaw programowania. Efekty kształcenia: Umiejętność tworzenia prostych aplikacji okienkowych w środowisku Microsoft Visual Studio, wykorzystujących techniki programowania obiektowego w języku C#. Treści kształcenia: 1. Wprowadzenie do WPF. Tworzenie interfejsu użytkownika. 2. Pojecie klasy i obiektu. Składniki klas – pola i metody. Konstruktory. 3. Okna dialogowe i kontrolki zawartości. Wiązanie danych. 4. Kompozycja. Kolekcje. Kontrolki list. 5. Dziedziczenie. 6. Polimorfizm. 7. Wyjątki. Style. 8. Grafika i animacja w WPF. Oprogramowanie: Microsoft Visual Studio 2008 lub nowsze (może być w wersji Express) wraz z dostępnym w nim systemem pomocy (MSDN). Dodatkowa literatura: 1. Adam Boduch, Wstęp do programowania w języku C#, Helion 2. Krzysztof Rychlicki-Kicior, Tworzenie aplikacji graficznych w .NET 3.0, Helion 3. Matthew MacDonald, Pro WPF in C# 2008: Windows Presentation Foundation with .NET 3.5 1/34 Co to jest programowanie obiektowe? Co to jest programowanie zdarzeniowe? Typowa aplikacja konsolowa (w C): #include "stdio.h" int main() { int a, b, c; printf("Podaj pierwszą liczbę: "); scanf("%d", &a); printf("Podaj drugą liczbę: "); scanf("%d", &b); c = a + b; printf("Suma = %d", c); return 0; } 2/34 Co to jest programowanie obiektowe? Co to jest programowanie zdarzeniowe? Typowa aplikacja konsolowa (w C++): #include "iostream" using namespace std; int main() { int a, b, c; cout << "Podaj pierwszą liczbę: "; cin >> a; cout << "Podaj drugą liczbę: "; cin >> b; c = a + b; cout << "Suma = " << c; return 0; } 3/34 Co to jest programowanie obiektowe? Co to jest programowanie zdarzeniowe? Typowa aplikacja konsolowa (w C#): using System; namespace ConsoleApplication1 { class Program { static void Main(string[] args) { int a, b, c; Console.Write("Podaj pierwszą liczbę: "); a = int.Parse(Console.ReadLine()); Console.Write("Podaj drugą liczbę: "); b = int.Parse(Console.ReadLine()); c = a + b; Console.Write("Suma = {0}", c); Console.ReadKey(); } } } 4/34 Jak powinna wyglądać aplikacja okienkowa? Krok pierwszy – tworzenie interfejsu użytkownika (wizualne lub w kodzie). 5/34 Jak powinna wyglądać aplikacja okienkowa? Krok drugi – obsługa zdarzeń. (chcemy, aby akcja użytkownika spowodowała wykonanie naszego kodu) void Oblicz(...) { ... ... ... } 6/34 Jak powinna wyglądać aplikacja okienkowa? Krok trzeci – interakcja z kontrolkami. (chcemy odczytać wprowadzone przez użytkownika dane, wykonać obliczenia i wyświetlić wynik) void Oblicz(...) { ... ... ... } 7/34 Dlaczego programowanie obiektowe? • • • • Jest bliższe postrzeganiu świata przez człowieka, który najpierw dostrzega pewne rzeczy, pojęcia (obiekty), a nie wykonywane przez nie czynności (funkcje). W programowaniu obiektowym, program to zbiór obiektów posiadających określone cechy (właściwości). Mogą one wchodzić między sobą w interakcje lub łączyć się w bardziej złożone struktury. Obiekt to serwer usług – może wykonać pewną operację, jeśli zostanie poproszony. Taka usługa nazywa się metodą obiektu. W aplikacji okienkowej obiektami są np. elementy, z których składamy interfejs użytkownika – okno, pola tekstowe, przyciski, etc. Język C# (C Sharp): • Prosty, nowoczesny, uniwersalny, język zorientowany obiektowo. • Zaprojektowany przez Microsoft, powiązany z platformą .NET. • Programy w nim napisane wymagają środowiska uruchomieniowego (takiego jak .NET lub Mono). 8/34 WPF – Windows Presentation Foundation • • • • • • • • • Interfejs programowania aplikacji okienkowych w systemie Windows. Wykorzystuje DirectX do rysowania okien i zawartości. Niezależność od rozdzielczości (oparcie się na „jednostkach logicznych”=1/96 cala) – umożliwia łatwe skalowanie i dopasowanie do rozdzielczości ekranu. Ułożenie kontrolek: dynamiczne, oparte na zawartości (dopasowują się do swojej zawartości oraz dostępnego miejsca). Obiektowy model rysowania oparty na grafice wektorowej. Wsparcie dla mediów i grafiki 3D. Deklaratywne tworzenie animacji. Style i szablony – pozwalają dopasowywać formatowanie i sposób renderowania elementów interfejsu. Deklaratywne*) tworzenie interfejsu użytkownika (XAML) – pozwala oddzielić wygląd interfejsu od kodu. *) Deklaratywne – czyli nie opisujemy kroków prowadzących do rozwiązania (algorytmu), a jedynie samo rozwiązanie. Nie mówmy jak ma być coś zrobione, ale co ma być zrobione. 9/34 XAML – Extensible Application Markup Language • • • • • • oparty na XMLu*) (deklaratywny) język do tworzenia interfejsu definiuje ułożenie (oraz inne cechy) kontrolek w oknie pozwala na podział pracy pomiędzy programistów i grafików (twórców interfejsu) XAML nie jest obowiązkowy – to samo można zrobić w kodzie, ale wymaga to większego nakładu pracy można korzystać z narzędzi wizualnych do generowania plików XAML (np. Microsoft Expression Blend) warto znać XAMLa aby móc w pełni wykorzystywać możliwości WPFa *) XML – uniwersalny język znaczników do strukturalnego reprezentowania danych 10/34 11/34 XML – wprowadzenie prawidłowy plik XML <!-- komentarz --> znacznik otwierający <lista> <osoba> Kowalski </osoba> <osoba imię="Piotr" nazwisko="Nowak"> <telefon numer="0123456789"/> </osoba> </lista> atrybuty znacznik pusty znacznik zamykający 12/34 XML – wprowadzenie nieprawidłowy plik XML <lista> <osoba>Nowak</Osoba> <osoba> <adres> </osoba> </adres> </lista> <osoba> Kowalski </osoba> 13/34 XAML • • • każdy znacznik odpowiada określonemu elementowi interfejsu możliwe jest zagnieżdżanie – używane do określenia zawierania np. jednych elementów w innych ustawianie właściwości przez atrybuty <Window ... Title="Okienko" Height="200" Width="300" FontSize="14"> <Grid> <Button Margin="30"> Nie dotykać </Button> </Grid> </Window> 14/34 Element <Window> – okno aplikacji <Window ... Title="Okienko" Height="200" Width="300" FontSize="14"> <Grid> <Button Margin="30"> Nie dotykać </Button> </Grid> </Window> Przykładowe atrybuty okna: • Title – tekst na pasku tytułowym • Height – wysokość • Width – szerokość • FontSize – rozmiar czcionki używanej przez wszystkie kontrolki w oknie 15/34 Układy zawartości <Window ... Title="Okienko" Height="200" Width="300" FontSize="14"> <Grid> <Button Margin="30"> Nie dotykać </Button> </Grid> </Window> Okno może zawierać tylko jeden element. Aby umieścić ich więcej musimy wykorzystać specjalny element, który posłuży za kontener dla innych kontrolek. • jest on odpowiedzialny za ułożenie kontrolek w oknie • dba o dopasowanie kontrolek do zawartości • oraz do dostępnego miejsca • • • • elementy nie powinny mieć ustalonego rozmiaru nie powinny mieć ustalonego położenia (współrzędnych) o te aspekty będzie dbał kontener różne rodzaje (typy) kontenerów będą kierować się różną logiką rozmieszczania elementów 16/34 <StackPanel> <Window ...> <StackPanel> <Button>jeden</Button> <Button>dwa</Button> <Button>trzy</Button> <Button>cztery</Button> </StackPanel> </Window> 17/34 <StackPanel> <Window ...> <StackPanel Orientation="Horizontal"> <Button>jeden</Button> <Button>dwa</Button> <Button>trzy</Button> <Button>cztery</Button> </StackPanel> </Window> 18/34 Przy pomocy atrybutów możemy sterować ułożeniem kontrolek: <Window ...> <StackPanel Orientation="Horizontal"> <Button VerticalAlignment="Top">jeden</Button> <Button VerticalAlignment="Center">dwa</Button> <Button VerticalAlignment="Bottom">trzy</Button> <Button VerticalAlignment="Stretch">cztery</Button> </StackPanel> </Window> • • VerticalAlignment HorizontalAlignment 19/34 Margin – dodaje odstęp od krawędzi kontenera i sąsiednich elementów: <Window ...> <StackPanel> <Button HorizontalAlignment="Left" Margin="5"> jeden</Button> <Button HorizontalAlignment="Right" Margin="5"> dwa</Button> <Button Margin="5">trzy</Button> <Button Margin="15, 5">cztery</Button> <Button Margin="30, 5, 15, 0">pięć</Button> </StackPanel> </Window> • marginesy sąsiadujących kontrolek sumują się! 20/34 Podobnie sterujemy ułożeniem zawartości wewnątrz kontrolki: <Window ...> <StackPanel> <Button HorizontalContentAlignment="Left"> jeden</Button> <Button HorizontalContentAlignment="Right"> dwa</Button> <Button HorizontalContentAlignment="Center"> trzy</Button> <Button>cztery</Button> </StackPanel> </Window> • • VerticalContentAlignment HorizontalContentAlignment 21/34 Podobnie sterujemy ułożeniem zawartości wewnątrz kontrolki: <Window ...> <StackPanel> <Button HorizontalAlignment="Center"> jeden</Button> <Button HorizontalAlignment="Center" Padding="5"> dwa</Button> <Button HorizontalAlignment="Center" Padding="15, 5"> trzy</Button> <Button HorizontalAlignment="Center" Padding="30, 0, 15, 5">cztery</Button> </StackPanel> </Window> • Padding steruje odstępem od zawartości kontrolki 22/34 <WrapPanel> <Window ...> <WrapPanel> <Button Margin="5">jeden</Button> <Button Margin="5">dwa</Button> <Button Margin="5">trzy</Button> <Button Margin="5">cztery</Button> <Button Margin="5">pięć</Button> <Button Margin="5">sześć</Button> </WrapPanel> </Window> 23/34 <DockPanel> „dołączone właściwości” <Window ...> <DockPanel> <Button DockPanel.Dock="Top">jeden</Button> <Button DockPanel.Dock="Left">dwa</Button> <Button DockPanel.Dock="Right">trzy</Button> <Button DockPanel.Dock="Bottom">cztery</Button> <Button DockPanel.Dock="Top">pięć</Button> <Button DockPanel.Dock="Right">sześć</Button> <Button>siedem</Button> </DockPanel> </Window> • kolejność elementów ma znaczenie! 24/34 <Grid> <Window ...> <Grid ShowGridLines="True"> <Grid.RowDefinitions> <RowDefinition/> <RowDefinition/> </Grid.RowDefinitions> <Grid.ColumnDefinitions> <ColumnDefinition/> <ColumnDefinition/> <ColumnDefinition/> </Grid.ColumnDefinitions> ... ... ... </Grid> </Window> • • tylko do testu elementy umieszczamy w polach siatki krok pierwszy – zdefiniowanie siatki 25/34 <Grid> <Window ...> <Grid> <Grid.RowDefinitions>...</Grid.RowDefinitions> <Grid.ColumnDefinitions>...</Grid.ColumnDefinitions> <Button>jeden</Button> <Button Grid.Row="1">dwa</Button> <Button Grid.Column="2">trzy</Button> <Button Grid.Row="1" Grid.Column="1">cztery</Button> </Grid> </Window> • krok drugi – rozmieszczenie elementów 26/34 <Grid> <Window ...> <Grid> <Grid.RowDefinitions>...</Grid.RowDefinitions> <Grid.ColumnDefinitions>...</Grid.ColumnDefinitions> <Button Grid.ColumnSpan="2">jeden</Button> <Button Grid.Row="1">dwa</Button> <Button Grid.Column="2" Grid.RowSpan="2">trzy</Button> <Button Grid.Row="1" Grid.Column="1">cztery</Button> </Grid> </Window> • element może rozciągać się na więcej niż jedno pole siatki 27/34 <Grid> <Window ...> <Grid> <Grid.RowDefinitions> <RowDefinition/> <RowDefinition/> </Grid.RowDefinitions> <Grid.ColumnDefinitions> <ColumnDefinition Width="auto"/> <ColumnDefinition Width="*"/> <ColumnDefinition Width="70"/> </Grid.ColumnDefinitions> ... ... </Grid> </Window> • • Width dla kolumn Height dla wierszy 28/34 Kontenery można dowolnie zagnieżdżać: <Grid> <Grid.ColumnDefinitions> <ColumnDefinition Width="auto"/> <ColumnDefinition Width="auto"/> <ColumnDefinition/> </Grid.ColumnDefinitions> <StackPanel> ... </StackPanel> <StackPanel Grid.Column="1" Orientation="Horizontal"> ... </StackPanel> <WrapPanel Grid.Column="2"> ... </WrapPanel> </Grid> 29/34 A jak zaprojektujemy nasze okienko? <Window ... Title="Obliczenia" Height="200" Width="300" FontSize="14"> ... </Window> 30/34 <Window ...> <Grid> <Grid.RowDefinitions> <RowDefinition Height="auto"/> <RowDefinition Height="auto"/> <RowDefinition Height="auto"/> <RowDefinition Height="auto"/> </Grid.RowDefinitions> <Grid.ColumnDefinitions> <ColumnDefinition Width="auto"/> <ColumnDefinition Width="*"/> </Grid.ColumnDefinitions> </Grid> </Window> • • • • cztery wiersze, dwie kolumny wysokość wierszy dopasowuje się do zawartości szerokość pierwszej kolumny dopasowuje się do zawartości szerokość kolumny z polem tekstowym – rozciągnięta 31/34 <Window ...> <Grid> <Grid.RowDefinitions>...</Grid.RowDefinitions> <Grid.ColumnDefinitions>...</Grid.ColumnDefinitions> <Label Margin="5">Pierwsza liczba:</Label> <Label Margin="5" Grid.Row="1">Druga liczba:</Label> <Label Margin="5" Grid.Row="2">Wynik:</Label> <TextBox Margin="5" Grid.Column="1"/> <TextBox Margin="5" Grid.Row="1" Grid.Column="1"/> <TextBox Margin="5" Grid.Row="2" Grid.Column="1" IsReadOnly="True"/> <Button Grid.Row="3" Grid.ColumnSpan="2" Margin="5" Padding="10,3" HorizontalAlignment="Right"> Oblicz</Button> </Grid> </Window> • • • Label – etykieta TextBox – pole tekstowe ◦ IsReadOnly – tylko do odczytu przycisk zajmuje cały wiersz 32/34 Jak dodać obsługę zdarzeń? również przy pomocy atrybutów: • <Button Click="Oblicz" ...>Oblicz</Button> // zawartość pliku Window1.xaml.cs: namespace WpfApplication1 { public partial class Window1 : Window { public Window1() { InitializeComponent(); } private void Oblicz(object sender, RoutedEventArgs e) { } } } Ta funkcja zostanie wywołana, gdy użytkownik naciśnie przycisk „Oblicz” 33/34 Jak odczytać dane z okna w kodzie programu? • najpierw musimy nazwać elementy, do których chcemy mieć dostęp: <TextBox Name="pierwsze" .../> <TextBox Name="drugie" .../> <TextBox Name="wynik" ... IsReadOnly="True"/> • następnie w pliku *.cs: private void Oblicz(object sender, RoutedEventArgs e) { int a = int.Parse(pierwsze.Text); int b = int.Parse(drugie.Text); int c = a + b; wynik.Text = c.ToString(); } • • • pierwsze.Text – zawartość pola tekstowego int.Parse(...) – konwersja tekstu na liczbę c.ToString() – konwersja zmiennej na tekst 34/34