Inżynieria Programowania Laboratorium 5 Część Wizualna. Paweł Paduch paduch@tu.kielce.pl



Podobne dokumenty
Inżynieria Programowania Laboratorium 3 Projektowanie i implementacja bazy danych. Paweł Paduch paduch@tu.kielce.pl

1 LINQ. Zaawansowane programowanie internetowe Instrukcja nr 1

Programowanie obiektowe i zdarzeniowe wykład 4 Kompozycja, kolekcje, wiązanie danych

Leszek Stasiak Zastosowanie technologii LINQ w

Informatyka II. Laboratorium Aplikacja okienkowa

ASP.NET MVC. Podstawy. Zaawansowane programowanie internetowe Instrukcja nr 3

xmlns:prism= c. <ContentControl prism:regionmanager.regionname="mainregion" />

Programowanie obiektowe

Wprowadzenie do Doctrine ORM

Podstawy technologii WWW

Instrukcja laboratoryjna cz.3

Laboratorium 7 Blog: dodawanie i edycja wpisów

Baza danych sql. 1. Wprowadzenie

Modelowanie obiektowe - Ćw. 1.

Instrukcja użytkownika systemu medycznego

Kostki OLAP i język MDX

Budowa aplikacji ASP.NET współpracującej z bazą dany do obsługi przesyłania wiadomości

Baza danych sql. 1. Wprowadzenie. 2. Repozytaria generyczne

WYKONANIE APLIKACJI OKIENKOWEJ OBLICZAJĄCEJ SUMĘ DWÓCH LICZB W ŚRODOWISKU PROGRAMISTYCZNYM. NetBeans. Wykonał: Jacek Ventzke informatyka sem.

Instrukcja laboratoryjna

Instalacja i obsługa aplikacji MAC Diagnoza EW

Prosta książka telefoniczna z wykorzystaniem zapisu do pliku

Instrukcja obsługi Zaplecza epk w zakresie zarządzania tłumaczeniami opisów procedur, publikacji oraz poradników przedsiębiorcy

5.4. Tworzymy formularze

Projektowanie baz danych za pomocą narzędzi CASE

Politechnika Poznańska Wydział Budowy Maszyn i Zarządzania

Instalacja i obsługa aplikacji MAC Diagnoza EP w celu wykonania Diagnozy rozszerzonej

Instrukcja obsługi Konfigurator MLAN-1000

Baza danych. Program: Access 2007

LABORATORIUM 8,9: BAZA DANYCH MS-ACCESS

Programowanie w środowisku graficznym GUI

Access - Aplikacja. Tworzenie bazy danych w postaci aplikacji

Instalacja systemu zarządzania treścią (CMS): Joomla

2.5 Dzielenie się wiedzą

INSTRUKCJA OBSŁUGI PROGRAMU PRZEDSZKOLE (CZ.1)

- Narzędzie Windows Forms. - Przykładowe aplikacje. Wyższa Metody Szkoła programowania Techniczno Ekonomiczna 1 w Świdnicy

WYPOŻYCZALNIA BY CTI INSTRUKCJA

Laboratorium 1 - Programowanie proceduralne i obiektowe

Programowanie obiektowe i zdarzeniowe wykład 1 Wprowadzenie do programowania zdarzeniowego

Instrukcja laboratoryjna nr.4

Uruchamianie bazy PostgreSQL

Wstęp. Skąd pobrać program do obsługi FTP? Logowanie

Maple i wykresy. 1.1 Najpierw należy się zalogować. Jak to zrobić zostało opisane w moim poprzednim tutorialu.

Palety by CTI. Instrukcja

Instrukcja obsługi. Helpdesk. Styczeń 2018

Budowa aplikacji ASP.NET współpracującej z bazą dany do obsługi przesyłania wiadomości

Dokumentacja systemu NTP rekrut. Autor: Sławomir Miller

Dodanie nowej formy do projektu polega na:

MATERIAŁY - udostępnianie materiałów dydaktycznych w sieci SGH

WPROWADZANIE ZLECEŃ POPRZEZ STRONĘ INSTRUKCJA UŻYTKOWNIKA

Platforma e-learningowa

Przykładowa dostępna aplikacja w Visual Studio - krok po kroku

Instrukcja laboratoryjna cz.6

System obsługi wag suwnicowych

Najważniejsze informacje dla klienta na temat Portalu Serwisowego D-Link Spis treści

Programowanie zaawansowane

Windows Workflow Foundation (wprowadzenie - prosty przykład Sequential Workflow):

Microsoft.NET: ASP.NET MVC + Entity Framework (Code First)

5.2. Pierwsze kroki z bazami danych

PWI Instrukcja użytkownika

Do korzystania ze strony elektronicznej rekrutacji zalecamy następujące wersje przeglądarek internetowych:

INSTRUKCJA OBSŁUGI BIULETYNU INFORMACJI PUBLICZNEJ

SUPLEMENT DO DYPLOMU

Kadry Optivum, Płace Optivum. Jak przenieść dane na nowy komputer?

Compas 2026 Personel Instrukcja obsługi do wersji 1.05

PTI S1 Tabele. Tabele. Tabele

Przygotowanie formularza do wypożyczenia filmu:

DOKUMENTY I GRAFIKI. Zarządzanie zawartością Tworzenie folderu Dodawanie dokumentu / grafiki Wersje plików... 7

LINQ TO SQL w dużym skrócie jest to zintegrowany język zapytao pozwalający na mapowanie relacyjnych baz danych na model obiektowy.

Nowa Netia administrator firmy Nagrywanie połączeń-zarządzanie

Microsoft.NET: LINQ to SQL, ASP.NET AJAX

Microsoft Access zajęcia 3 4. Tworzenie i wykorzystanie kwerend, formularzy i raportów

Nabór Bursy/CKU. Do korzystania ze strony elektronicznej rekrutacji zalecamy następujące wersje przeglądarek internetowych:

Zaawansowane aplikacje internetowe - laboratorium

Instrukcja obsługi programu VisitBook Semieta Lite

Załącznik nr 8. do Studium Wykonalności projektu Sieć Szerokopasmowa Polski Wschodniej województwo podkarpackie

LK1: Wprowadzenie do MS Access Zakładanie bazy danych i tworzenie interfejsu użytkownika

System Obsługi Zleceń

SYSTEM ZARZĄDZANIA RELACJAMI Z KLIENTEM CRM7

Compas 2026 Vision Instrukcja obsługi do wersji 1.07

Rys. 1. Główne okno programu QT Creator. Na rysunku 2 oznaczone zostały cztery przyciski, odpowiadają kolejno następującym funkcjom:

Rozdział 3. Zapisywanie stanu aplikacji w ustawieniach lokalnych


2. Kliknij Insert->Userform. Jeżeli Toolbox nie pojawi się automatycznie, kliknij View -> Toolbox. Otrzymany widok powinien być jak poniżej.

Wprowadzenie do projektu QualitySpy

D:\DYDAKTYKA\ZAI_BIS\_Ćwiczenia_wzorce\04\04_poprawiony.doc 2009-lis-23, 17:44

Podręcznik aplikacji PANTEON dla IS PAN. Spis treści. Wersja 1.0

Edycja szablonu artykułu do czasopisma

Bazy danych Karta pracy 1

Zbieranie kontaktów.

Instrukcja użytkownika systemu medycznego. Pracownik medyczny Lekarz ZDLR

Sprawdzenie czy połączenie przebiegło poprawnie if (mysqli_connect_errno()) { echo Błąd; Połączenie z bazą danych nie powiodło się.

Instrukcja użytkownika systemu medycznego

Aplikacje WWW - laboratorium

Budowa aplikacji ASP.NET współpracującej z bazą dany do obsługi przesyłania wiadomości

Stosowanie, tworzenie i modyfikowanie stylów.

Wybieramy File->New->Project Wybieramy aplikację MFC->MFC Application jak na rysunku poniżej:

6. Formularze tabelaryczne, obiekty nawigacji - rozgałęzienia

plansoft.org Zmiany w Plansoft.org Błyskawiczny eksport danych PLANOWANIE ZAJĘĆ, REZERWOWANIE SAL I ZASOBÓW

Transkrypt:

Inżynieria Programowania Laboratorium 5 Część Wizualna Paweł Paduch paduch@tu.kielce.pl 11-05-2013

Rozdział 1 Wstęp Na dzisiejszych zajęciach poznamy jeden ze sposobów tworzenia okienkowej aplikacji w środowisku Visual Studio 2010 wykorzystując WPF (Windows Presentation Foundation. Oczywiście najpełniejszym źródłem wiedzy jest dokumentacja ze stron twórcy. http://msdn.microsoft.com/en-us/library/ms754130(v=vs.100).aspx WPF w porównaniu do klasycznego API Windows Form ma o wiele większe możliwości. Łączy w sobie kilka technologii. Poza klasycznym używaniem formatek z kontrolkami, można tworzyć grafiki 2D (tak jak w przypadku GDI+ System.Drawing.dll), obsługa grafiki 3D (wcześniej API DirectX), odtwarzanie strumieni wideo (wcześniej API Windows Media Player), oraz zarządzanie przepływem dokumentów. Wszystkie te technologie zostały zunifikowane do wspólnego API pod nazwą WPF. Celem dzisiejszych zajęć jest poznanie podstaw WPF. Dowiemy się jak stworzyć i skonfigurować proste okienko. Dodać kontrolki menu, okienka wprowadzania tekstu, guziki i tabelki. A co najważniejsze, będziemy operować na naszej bazie danych za pomocą wcześniej przygotowanej biblioteki RezerwacjeLib. 1

Rozdział 2 Na początek Na ostatnich zajęciach stworzyliśmy, bibliotekę dostępu do bazy danych. Posłuży nam ona za warstwę połączeniową. To z jej obiektów i metod będziemy korzystać gdy będziemy chcieli pobrać, dodać czy usunąć rekordy. Zanim jednak przejdziemy do tworzenia aplikacji wprowadzimy jeszcze kilka zmian w RezerwacjeLib. 2.1 Nazewnictwo Ostatnio problemem okazały się niezbyt trafnie dobrane nazwy np. musieliśmy tworzyć klasę Uzytkownicy, która operowała na tablicy Osoby. (klasa Osoby jest automatycznie generowane przez Entity Framework), mieliśmy Role zamiast Uprawnień itp. Poza tym w bazie nazwy tablic zwykle określały liczbę mnogą elementów w nich trzymanych (np. Osoby. Tytuly itd.) a np. Rezerwacja już nie. Kolejny problem do duże i małe litery, niektórzy stosowali małe litery w nazwach tabel to z kolei wprost przekładało się na nazwy klas wygenerowanych przez EF. Aby jednoznacznie i w sposób zunifikowany zrobić porządek z nazwami proponuję następującą nomenklaturę tabel w bazie: DniKalendarzaAkademickiego KalendarzeAkademickie Osoby Propozycje PropozycjeRezerwacje PrzedzialyCzasowe Rezerwacje RezerwacjeOsoby SchematyGodzinowe StanyRezerwacji 2

TypyRezerwacji TypyZasobow (nowa tabelka) Tytuly Uprawnienia Wiadomosci Zasoby Dojdzie też jedna tabelka 2.1TypyZasobow: Do tablicy Zasoby dodamy też pole IdTypuZasobu Typ tinyint varchar(50) Tabela 2.1: Typy zasobów IdTypuZasobu będące kluczem obcym i mającym zależność z tabeleką TypyZasobow. Oczywiście pamiętamy by IdTypuZasobu w TypyZasobow ustawić jako klucz główny oraz Indentity. Po tych zmianach zapisujemy wszystko i robimy aktualizację modelu Rezerwacje.edmx w RezerwacjeLib. Tabele z nowymi nazwami zostaną naniesione, niestety stare tabele zostaną powodując błędy w stylu: Error 7 Error 11007: Entity type KalendarzAkademicki is not mapped. Tabelki powodujące błędy należy usunąć oraz jeszcze raz zaktualizować model. Gdy nie ma już błędów w modelu należy przebudować bibliotekę i poprawić nazwy w plikach *.cs. Kolejne problemy z nazwami to nazwy klas wygenerowanych przez EF oraz klas napisanych przez nas w celu obsłużenia wskazanych tabel. 1 Można je rozróżnić dodając jakiś prefiks lub sufiks (np. Class). Jednak jeszcze lepszą metodą będzie skorzystanie z faktu, że klasy generowane przez EF są klasami częściowymi (ang. partial). Proszę sobie przejrzeć plik RezerwacjeDesigner.cs. W pliku tym nie możemy dodawać nowych metod. W ogóle nie powinniśmy tam nic zmieniać, bo po aktualizacji plik jako generowany automatycznie zostanie nadpisany. Możemy jednak wygenerowane klasy rozszerzyć o nową funkcjonalność w swoich plikach. Zanim to zrobimy uporządkujmy sobie nazewnictwo naszych plików podając nazwy takie jak w bazie np. Osoby.cs, Rezerwacje.cs itd. Najlepiej to zrobić zmieniając nazwę plików *.cs w solution explorerze potwierdzając propozycję zamiany nazewnictwa w reszcie projektu. Następnie zmieniając nazwy klas (już w pliku) podajemy przy okazji kwalifikator partial (bez tego słowa kluczowego będą zgłaszane błędy, że klasa o podanej nazwie istnieje). Tak jak to jest w listingu 2.1. 2.2 Podstawowe metody W dzisiejszym programie będziemy potrzebowali następującej funkcjonalności: 1 Istnieje jeszcze jedna metoda, mapowania nazw. Gdy w modelu wygenerowanym z bazy (plik *.edmx) wybierzemy z menu kontekstowego danej klasy Table Mapping możemy dostosować nazewnictwo wygenerowane automatycznie do nazwenictwa dla nas odpowiedniego. 3

pobieranie zbioru wszystkich obiektów danego typu np. Tytułów IQueryable<Tytuly> getall() dodawanie pojedynczego obiektu danego typu np. void dodaj(tytuly tytul) usuwanie podanego obiektu np. void usun(tytuly tytul) nanoszenie stanu kontekstu do bazy void zapisz() Przykładowo dla listy tytułów podstawowa klasa Tytul powinna zawierać metody jak na listingu 2.1 Nie oznacza to, że jeżeli mieliśmy już jakieś inne funkcje (np. wyszukaj tytuł po id) mamy je usuwać. 1 using System; 2 using System.Collections.Generic; 3 using System.Linq; 4 using System.Text; 5 Listing 2.1: Klasa Tytuly.cs 6 namespace RezerwacjeLib 7 { 8 public partial class Tytuly 9 { 10 private rezerwacjeentities context = new rezerwacjeentities(); 11 12 public IQueryable<Tytuly> getall() 13 { 14 return from wybrane in context.tytuly select wybrane; 15 } 16 17 public void dodaj(tytuly tytul) 18 { 19 context.tytuly.addobject(tytul); 20 } 21 22 public void usun(tytuly tytul) 23 { 24 context.tytuly.deleteobject(tytul); 25 } 26 27 public void zapisz() 28 { 29 context.savechanges(); 30 } 31 } 32 } Powinniśmy zaimplementować powyższe metody do klas: Zasoby, Uprawnienia, Tytuly, StanyRez, TypyRez oraz TypyZasobow. Dodatkowo z poprzednich zajęć powinniśmy mieć funkcję znajdująca po loginie i haśle jak w listingu 2.2 4

Listing 2.2: Szukaj po loginie i haśle 1 public Osoby znajdzosobepologinieihasle(string login, string haslo) 2 { 3 var osoby = (from os in context.osoby where os.login == login && os.haslo == haslo select os).firstordefault(); 4 return osoby; 5 } Przyda nam się też funkcja zwracająca wszystkie osoby. Można napisać nową podobnie jak w listingu 2.1 lub wykorzystać np. funkcję, która szuka po nazwisku z maską i podać gwiazdkę aby wyszukała wszystkie wystąpienia. Reszta nie będzie nam dziś potrzebna choć dla pełnej obsługi można zrobić. Przypominam bibliotekę przebudowujemy za pomocą klawisza F6. 5

Rozdział 3 Nowy projekt Z górnego menu wybieramy: File New Project. W okienku wyboru nowego projektu zaznaczamy Visual C# Windows WPF Application. Na dole wpisujemy nazwę projektu RezerwacjeApp i potwierdzamy OK. (rys. 3.1) Rysunek 3.1: Okienko wybierania nowego projektu. Otworzy nam się pierwsze domyślne okno główne, pod spodem (jeżeli nie ma to włączyć w menu view) mamy kod XAML. Jest to plik xmlowy opisujący wygląd naszego okna. Aplikację WPF można stworzyć na 3 sposoby. W czystym XAML u wtedy odpowiedni kod jest zawarty w tagach <x:code>, w czystmy C# bez XAML, wtedy właściwości poszczególnych elementów przypisujemy z kodu oraz najpopularniejszy i sugerowany sposób tzw. Code-Behind. Część wizualna - zachowanie interfejsu użytkownika to kod XAML natomiast oprogramowanie zdarzeń w kodzie C#. 6

My będziemy tworzyć aplikację według tego trzeciego sposobu. Większość właściwości można wyklikać zarówno w samym oknie pokazującym przykładowy wygląd jak i w okienku Properties. Np, sposób wyrównywania, kolory, podpięte eventy. Jak ktoś chce można edytować plik XAML i obserwować efekty w oknie podglądu. Są też dodatkowe programy do edycji XAML jak chociażby Expression Blend. Zmieńmy tytuł okna na Rezerwacje (niezalogowany). Można też pobawić się kolorami, np. dać tło w postaci cieniowanej. Zanim przejdziemy dalej, pamiętajmy aby dodać referencje do naszej biblioteki (RezerwacjeLib), System.Data.Entity oraz dodać plik konfiguracji, w którym jest między innymi opis połączenia z bazą (App.config). W każdym nowym pliku *.cs dodajemy też informację o używanej przestrzeni nazw using RezerwacjeLib;. Jednym z takich plików jest automatycznie stworzony Main- Window.xaml.cs w którym zawarta jest logika działania okna MainWindow. Identycznie jak robiliśmy w przypadku aplikacji konsolowej na poprzednich zajęciach. 3.1 Menu Na początek dodajmy proste menu. Pod tagiem <Grid> umieszczamy kod jak na listingu 3.1 Listing 3.1: Menu w MainWindow.xaml 1 <Menu HorizontalAlignment="Left" Name="menuGlowne"> 2 <MenuItem Header="Zaloguj" Name="Logowanie" Click="Logowanie_Click"/> 3 <MenuItem Header="Osoby" Name="Osoby" Click="Osoby_Click"/> 4 <MenuItem Header="Słowniki" Name="Slowniki" Click="Slowniki_Click"> 5 <MenuItem Header="Zasoby" Name="Zasoby" Click="Zasoby_Click"/> 6 <MenuItem Header="Typy Zasobów" Name="TypyZasobow" Click="TypyZasobow_Click"/ > 7 <MenuItem Header="Typy Rezerwacji" Name="TypyRezerwacji" Click=" TypyRezerwacji_Click"/> 8 <MenuItem Header="Stany Rezerwacji" Name="StanyRezerwacji" Click=" StanyRezerwacji_Click"/> 9 <MenuItem Header="Tytuły" Name="Tytuly" Click="Tytuly_Click"/> 10 <MenuItem Header="Uprawnienia" Name="Uprawnienia" Click="Uprawnienia_Click"/> 11 </MenuItem> 12 </Menu> Wartość atrybutu Click to nazwa funkcji wywoływanej do obsługi kliknięcia w dany element menu. Z menu Properties wybieramy zakładkę Events i odnajdujemy zdarzenie Click. Powinna być tam już wpisana nazwa naszej metody. Tylko gdzie jest jej implementacja? Jeszcze nie ma ale do czasu. Teraz wystarczy kliknąć dwukrotnie tę nazwę. Otworzny nam się plik MainWindow.xaml.cs a kursor ustawi na nowo wygenerowanym szkielecie funkcji obsługującej zdarzenie kliknięcia. Tak należy postąpić ze wszystkimi funkcjami. Gdy wszystko jest już poprawione powinniśmy móc skompilować (F5). 7

Rozdział 4 Logowanie Pierwszą, czynnością w naszym programie będzie zalogowanie się do systemu. Logowanie będzie bardzo prymitywne. Poprosimy użytkownika o podanie loginu i hasła. Program za pomocą wcześniej stworzonej metody znajdzosobe- PoLoginieIHasle odszuka użytkownika w bazie. Jeżeli takiego nie znajdzie uruchomi nam się aplikacja w trybie niezalogowany. Na chwilę obecną nie będziemy rozróżniać uprawnień i poza wpisem w tytule okienka nie będzie żadnej różnicy pomiędzy użytkownikami. Jednak jesteśmy gotowi do rozpoznania według jakiego schematu uprawnień program ma działać. 4.1 Okno logowania Z menu Solution Explorer wybieramy Add Window. Nadajemy nazwę WinLogowanie. Do okienka dodajemy dwie kontrolki typu Label jednką TextBox, jedną PasswordBox oraz dwie typu Button Etykietki to napisy odpowiednio Login i Hasło. Guziki to Zaloguj i Anuluj. Pola do wprowadzania tekstu powinny mieć nazwy passwordboxhaslo oraz textboxlogin. Guziki nazywamy buttonzaloguj i buttonanuluj. Mniej więcej jak na rys. 4.1 4.2 Obsługa Logowania W obrębie bieżącej przestrzeni nazw (np. tworząc osobny plik Enumeracje.cs) tworzymy enumerację jak na 4.1 Tworzymy też nowy typ danych reprezentujący wiersz wyszukanych osób. (to nam się przyda nieco dalej). 1 using System; 2 using System.Collections.Generic; 3 using System.Linq; 4 using System.Text; 5 6 namespace Rezerwacje 7 { 8 public enum LoginResult 9 { 10 Canceled,LoginOk,BadLogin 11 } Listing 4.1: Stany logowania 8

Rysunek 4.1: Projekt okienka logowania. 12 13 public class WierszOsoby 14 { 15 public long IdOsoby { get; set; } 16 public string Tytul { get; set; } 17 public string Imie { get; set; } 18 public string Nazwisko { get; set; } 19 public string Login { get; set; } 20 } 21 22 class Enumeracje 23 { 24 } 25 } Do pliku WinLogowanie.xaml.cs dodajemy zmienne określające jak przebiegło logowanie (listing 4.2 Listing 4.2: Zmienne w WinLogowanie.xaml.cs 1 public Osoby zalogowanaosoba = null; 2 private LoginResult lr; // rezultat logowania 3 public LoginResult loginresult //ale tylko do odczytu 4 { 5 get { return lr; } 6 } Podpinamy też obsługę zdarzeń po kliknięciu guzików Zaloguj oraz Anuluj. jak na listingach 4.3 oraz 4.4 Listing 4.3: Zaloguj WinLogowanie.xaml.cs 1 private void buttonloguj_click(object sender, RoutedEventArgs e) 2 { 3 Osoby users = new Osoby(); 4 zalogowanaosoba = users.znajdzosobepologinieihasle(this.textboxlogin.text, this. passwordboxhaslo.password); 5 if (zalogowanaosoba!= null) 6 { 7 lr = LoginResult.LoginOk; 9

8 } 9 else 10 { 11 lr = LoginResult.BadLogin; 12 } 13 this.close(); 14 } Listing 4.4: Anuluj WinLogowanie.xaml.cs 1 private void buttonwyjdz_click(object sender, RoutedEventArgs e) 2 { 3 zalogowanaosoba = null; 4 lr = LoginResult.Canceled; 5 this.close(); 6 } Teraz jeszcze tylko pozostaje obsłużyć logowanie w MainWindow.xaml.cs. Potrzebne będą nam 3 funkcje: Zaloguj Wyloguj oraz obsługa kliknięcia w menu. Przechodzimy do pliku MainWindow.xaml.cs W klasie MainWindow dodajmy zmienną private Osoby zalogowany = null; Dodajemy funkcję Zaloguj jak w listingu 4.5. Listing 4.5: Zaloguj w MainWindow.xaml.cs 1 private Osoby zaloguj() 2 { 3 WinLogowanie winlogin = new WinLogowanie(); 4 winlogin.showdialog(); 5 6 Osoby ret = winlogin.zalogowanaosoba; 7 switch (winlogin.loginresult) 8 { 9 case LoginResult.LoginOk: 10 if (ret!= null) 11 { 12 this.title = "Rezerwacje (zalogowany " + ret.imie + " " + ret. Nazwisko + " <" + ret.uprawnienia.nazwa + "> )"; 13 this.logowanie.header = "Wyloguj"; 14 } 15 else 16 { 17 MessageBox.Show("Dziwne Osoba == null choć login ok"); 18 throw new Exception("Osoba == null choć została znaleziona"); 19 } 20 break; 21 case LoginResult.BadLogin: 22 MessageBox.Show("Nieprawidłowe logowanie"); 23 break; 24 case LoginResult.Canceled: 25 break; 26 default: 27 throw new Exception("Nieobsłużony case"); 28 } 29 return ret; 30 } 10

Tworzy ona nowy obiekty typu WinLogowanie oraz wyświetla go jako dialog (czyli czeka na zamknięcie). Następnie odczytuje co zwróciło okienko, jeżeli użytkownik został znaleziony dostaniemy jego instancję oraz potwierdzenie poprawnego logowania, w przypadku niepowodzenia lub anulowania zalogowanaosoba będzie miała wartość null. Na tej podstawie możemy określić różne zachowania. Np. można ustawić tytuł głównego okna z informacją o zalogowanej osobie, oraz zmienić napis na przycisku logowania w głównym menu. Wylogowanie będzie dużo prostsze (listing 4.6). Działanie wylogowania wprowadza tylko zmiany kosmetyczne, ale w przyszłości można jeszcze zawrzeć np. zatwierdzenie wykonanych zmian lub pytanie czy na pewno wylogować. Listing 4.6: Wylogowanie w MainWindow.xaml.cs 1 private void wyloguj() 2 { 3 zalogowany = null; 4 this.logowanie.header = "Zaloguj"; 5 this.title = "Rezerwacje (niezalogowany)"; 6 } Odszukujemy wygenerowaną funkcję Logowanie Click i implementujemy kod jak na listingu 4.7 Listing 4.7: Obsługa Logowanie Click w MainWindow.xaml.cs 1 private void Logowanie_Click(object sender, RoutedEventArgs e) 2 { 3 if (zalogowany == null) //jak nie zalogowani to się logujemy 4 { 5 if ((zalogowany = zaloguj())!= null) 6 { 7 //miejsce na dodatkowe czynności wiedząc kto się zalogował 8 } 9 } 10 else //jak zalogowani to się wylogujemy 11 wyloguj(); 12 } Kolejną modyfikacją jaką można dokonać jest automatyczne utworzenie okna logowania przy załadowaniu okna głównego. W tym celu należy w oknie głównym obsłużyć zdarzenie Loaded jak na listingu 4.8. Listing 4.8: Obsługa Window Loaded w MainWindow.xaml.cs 1 private void Window_Loaded(object sender, RoutedEventArgs e) 2 { 3 zalogowany = zaloguj(); 4 } Żeby jeszcze bardziej ułatwić użytkownikowi logowanie, można ustawić kursor w okienku do wprowadzania loginu. W tym celu należy w konstruktorze WinLogowanie wywołać metodę Focus() na obiekcie textboxlogin. Jeżeli uda nam się skompilować i uruchomić naszą aplikację, powinniśmy na wstępie dostać okienko logowania. Po zalogowaniu powinniśmy mieć możliwość wylogowania oraz zalogowania ponownego. W przypadku błędu związanego z połączeniem, sprawdzić czy nie zapomnieliśmy o pliku App.config. 11

Rozdział 5 Edycja danych w prostych tabelach Do tej pory operacje na bazie były dość ograniczone. Jedynie jedno zapytanie o użytkownika. Nie wymagało to specjalnych konstrukcji do przeglądania danych lub ich poprawiania czy dodawania. Chcąc operować na większej liczbie danych posłużymy się tabelką. Na początku będzie to tabelka, w której umieścimy odczytane dane. Scenariusz będzie następujący: Klikam w menu Słowniki Tytuły Wywoływana jest procedura obsługi kliknięcia Tytuly Click Otwierane jest nowe okienko z tabelką Tabelka jest wypełniana danymi z bazy Zamykam okno. Zacznijmy od utworzenia nowego okna WinTytuly. Nadajmy mu tytuł Tytuły. Dodajmy nowe źródło danych. Z lewej strony z paska narzędzi należy wybrać zakładkę Data Sources. Gdy nie dodawaliśmy wcześniej żadnego źródła danych zobaczymy tylko puste miejsce z informacją aby takie źródło dodać. Klikamy w Add New Data Source... wyskoczy nam okienko kreatora dodawania nowego źródła danych. (rys. 5.1). Wybieramy Object klikamy dalej. W kolejnym kroku (Rys. 5.2) wybieramy RezerwacjeLib. Teraz wystarczy przeciągnąć nazwę interesującej nas tabelki na nowe okno. Powstanie element DataGrid wraz ze zdefiniowanymi kolumnami. Tabelkę i okno musimy nieco dopasować by jedno w drugim się mieściło. Teraz należałoby wyświetlić okienko po naciśnięciu odpowiedniego elementu z menu. W tym celu wypełniamy funkcję Tytuly Click jak na listingu 5.1. Listing 5.1: Obsługa Tytuly Click w MainWindow.xaml.cs 1 private void Tytuly_Click(object sender, RoutedEventArgs e) 2 { 12

Rysunek 5.1: Dodawanie nowego źródła danych. Rysunek 5.2: Dodawanie nowego źródła danych. 13

3 WinTytuly oknotytulow = new WinTytuly(); 4 oknotytulow.show(); 5 } Po skompilowaniu i uruchomieniu powinniśmy móc zobaczyć okno z tabelką. Niestety tabelka jeszcze jest pusta. Należy teraz wypełnić ją danymi. Na szczęście jest to kwestia dopisania trzech linijek kodu. Otwieramy plik WinTytuly.xaml.cs. Pamiętamy by dopisać using RezerwacjeLib;. Odszukujemy wygenerowaną funkcję Window Loaded i dodajemy zmienną tytuly oraz modyfikujemy ostatnią linijkę jak to jest pokazane w przykładzie 5.2. Listing 5.2: Zmiany w WinTytuly.xaml.cs 1 Tytuly tytuly = new Tytuly(); 2 private void Window_Loaded(object sender, RoutedEventArgs e) 3 { 4 System.Windows.Data.CollectionViewSource tytulyviewsource = ((System.Windows.Data.CollectionViewSource)(this.FindResource("tytulyViewSource"))); 5 // Load data by setting the CollectionViewSource.Source property: 6 tytulyviewsource.source = tytuly.getall(); 7 } Widzimy, że po pierwsze stworzyliśmy sobie obiekt klasy Tytuly (to w nim zaimplementowaliśmy metodę zwracającą wszystkie rekordy getall()). Następnie ustalamy, że źródłem danych jest lista obiektów znalezionych przez metodę getall(). Ponownie skompilujmy i zobaczmy wygląd nowego okna z tytułami. Pozostaje nam zaimplementować obłsugę edycji danych. W okienku WinTytuly dodajemy dwa guziki Zapisz i Wyjdź. Oprogramujemy je dwoma poleceniami (tak tylko dwoma :) ). tytuly.zapisz(); Close(); 5.1 Pierwsze samodzielne zadanie Po tym dość długim tutorialu, czas na pierwsze samodzielne zadanie. Oprogramuj tak jak w przykładzie edycje dla tabel: TypyZasobow StanyRez TypyRez Uprawnienia Tabelka z zasobami jest nieco trudniejsza dlatego zajmiemy się nią w osobnym rozdziale. 14

Rozdział 6 Kolumna z polami ComboBox Ponieważ w tabeli Zasoby jest pole IdTypuZasobu będące kluczem obcym do tabelki TypyZasobow tę kolumnę potraktujemy specjalnie. Użyjemy kontrolki typu ComboBox z możliwością wybrania typu zasobu dla danego wiersza. Tak jak na rysunku 6.1. Rysunek 6.1: Przykładowe okno zasobów. W polu typu Combo mamy słownik, w którym określamy, które pole będzie wyświetlane (Typ) oraz za pomocą którego pola powiążemy słownik z zasobami (IdTypuZasobu). Definicja kolumny będzie wyglądać jak na listingu 6.1. Listing 6.1: Zastosowanie pola ComboBox w tabelce 1 <DataGridComboBoxColumn x:name="combo" 15

2 Header="Typ" 3 Width="Auto" 4 CanUserSort="True" 5 SortMemberPath="TypyZasobow.Typ" 6 DisplayMemberPath="Typ" 7 SelectedValueBinding="{Binding Path=IdTypuZasobu}" 8 SelectedValuePath="IdTypuZasobu"/> Dodatkowo aby wypełnić kontrolkę ComboBox danymi trzeba w pliku Win- Zasoby.xaml.cs dodać ładowanie typów zasobów. Czyli najpierw stworzyć obiekt typu TypyZasobow następnie za jego pomocą wypełnić combo.itemssource jak w listingu 6.2 w linii 8. Konwersja ToList jest potrzebna, aby umożliwić użytkownikowi sortowanie po wybranych kolumnach. Listing 6.2: Załaduj typy zasobów 1 Zasoby zasoby = new Zasoby(); 2 TypyZasobow typyzasobow = new TypyZasobow(); 3 private void Window_Loaded(object sender, RoutedEventArgs e) 4 { 5 System.Windows.Data.CollectionViewSource zasobyviewsource = ((System.Windows.Data.CollectionViewSource)(this.FindResource("zasobyViewSource"))); 6 // Load data by setting the CollectionViewSource.Source property: 7 zasobyviewsource.source = zasoby.getall().tolist(); //Listę da się sortować 8 combo.itemssource = typyzasobow.getall().tolist(); 9 } 16

Rozdział 7 Punktacja Praca na zajęciach oceniana będzie następująco: Uporanie się z nazewnictwem 0,5 pkt. Stworzenie/uzupełnienie podstawowych metod 0,5 pkt. Stworzenie nowego projektu wraz z menu 0.5 pkt. Zaimplementowanie okna logowania 1 pkt. Zaimplementowanie edycji tytułów, (według tutoriala) 0,5 pkt. Zaimplementowanie obsługi reszty tablic słownikowych z punktu 5.1 1,5 pkt. Zaimplementować obsługę tabelki Zasoby według przykładu podanego w punkcie 6 0,5 pkt. Proszę zachować kolejność wykonywania poszczególnych zadań. Pominięcie niektórych etapów może skutkować brakiem możliwości wykonania kolejnych punktów. Ocenie będą podlegać tylko kompilujące się i działające przykłady. 17