Programowanie w środowiskach graficznych Wykład 2 Windows Forms
.NET Framework Generacja Data Środowisko Dystrybuowane z 1.0 2002-02-13 Visual Studio.NET N/A 1.1 2003-04-24 Visual Studio.NET 2003 2.0 2005-11-07 Visual Studio 2005 3.0 2006-11-06 Expression Blend 3.5 2007-11-19 Visual Studio 2008 Windows Server 2003 Windows Server 2003 R2 Windows Vista, Windows Server 2008 Windows 7, Windows Server 2008 R2 4.0 2010-04-12 Visual Studio 2010 N/A 4.5 2012-08-15 Visual Studio 2012 4.5.1 2013-10-17 Visual Studio 2013 Windows 8, Windows Server 2012 Windows 8.1, Windows Server 2012 R2 2
Windows Forms (WinForms) Klasy należące do.net Framework używane do tworzenia aplikacji z graficznym interfejsem użytkownika dla systemów Windows przestrzeń nazw System.Windows.Forms Kategorie klas: podstawowe (np. Application, Form) kontrolki dziedziczące z klasy Control (np. Button) komponenty nie dziedziczące z klasy Control (np. Timer, ToolTip) standardowe okna dialogowe (np. OpenFileDialog, PrintDialog) 3
Przykładowy program using System; using System.Windows.Forms; namespace MyWindowsApp { public class MainWindow : Form { static void Main (string[] args) { Application.Run (new MainWindow ()); } } } MessageBox.Show ("That s all", "Sample program", MessageBoxButtons.OK, MessageBoxIcon.Stop); 4
Windows Forms generowanie projektu 1/2 Generowany standardowo program tworzy klasę aplikacji oraz pusty formularz. Klasa formularza rozbita jest na dwa pliki za pomocą konstrukcji partial class języka C#. Są to pliki np. Form1.cs oraz Form1.Designer.cs. Programista standardowo modyfikuje Form1.cs (np. dodaje tam obsługę zdarzeń, własne dane i metody związane z formularzem) 5
Windows Forms generowanie projektu 2/2 Do pliku Form1.Designer.cs automatycznie trafiają wszelkie zmiany formularza dokonywane wizualnie (designerem), np. przeciągnięcie kontrolki z przybornika, zmiana rozmiaru, wyglądu, zawartości startowej, struktura kontrolek (która jest na której), itp. Raczej nie powinno się modyfikować tego pliku ręcznie. Logikę biznesową aplikacji (czyli dane, na których działamy oraz metody je obsługujące) umieszczamy zwykle w osobnych klasach (Project -> Add Class) i komunikujemy się z formularzem jawnie za pomocą metod. Jest to separacja logiki od formularza. Pozwala to m.in. na zmianę technologii, czyli np. przejście z Windows Forms do WPF czy SilverLight. Logika pozostaje bez zmian, dopisujemy nowy GUI, podmieniamy komunikację. 6
Model-View-Controller (MVC) Koncepcja ta odpowiada częściowo modelowi MVC. Logika biznesowa aplikacji to Model. Model powinien być samodzielny. Formularz pełni tu rolę View i Controller-a, bo zwykle równocześnie wyświetla dane oraz umożliwia ich modyfikację. Można też jawnie rozdzielić te dwie role, wprowadzając pomocnicze klasy. Według MVC równocześnie może być aktywnych wiele View (widoków), prezentujących dane Modelu na różne sposoby (wykresy, okna, zakładki, formularze). Podobnie (rzadko) może też istnieć wiele Controller-ów, ale tylko jeden z nich steruje Modelem. 7
Obsługa zdarzeń GUI jest oparty na zdarzeniach wynikających z interakcji z użytkownikiem Event handlers metody wywoływane do obsługi zdarzeń Dla każdego zdarzenia istnieje definicja sygnatury dla metody obsługi tego zdarzenia (delegate) dla każdego zdarzenia trzymana jest lista referencji do metod zapisanych na to zdarzenie w momencie wystąpienia zdarzenia wszystkie metody zapisane na tej liście są wywoływane (kolejność ich wywoływania nie jest zdefiniowana) 8
Przykład zdarzenia: na żądanie zamknięcia formularza FormClosing namespace MyApplication { public class MyForm : Form { public MyForm () { FormClosing += new FormClosingEventHandler (OnClosing); } private void OnClosing (Object sender, FormClosingEventArgs e) { if (MessageBox.Show ("Sure to close?", "Question", MessageBoxButtons.YesNo) == DialogResult.No) { e.cancel = true; } } } } 9
Przykład zdarzenia: zamknięcie aplikacji: ApplicationExit namespace MyApplication { static class Program { static void Main () { Application.ApplicationExit += new EventHandler (Program_ApplicationExit); Application.Run (new MyForm ()); } private static void Program_ApplicationExit ( Object sender, EventArgs e) { MessageBox.Show ("That's all"); } } } 10
Klasa Application Reprezentuje program, zawiera statyczne metody i właściwości do zarządzania aplikacją Run(Form f) główna pętla obsługi komunikatów oraz wyświetlenie wskazanego formularza Exit() informuje wszystkie okna o zamknięciu i je zamyka ExitThread() zamyka wszystkie okna wątku DoEvents() przydatne podczas długotrwałych obliczeń (umożliwia obsługę oczekujących zdarzeń) EnableVisualStyles() obsługa stylów Windows XP zdarzenie Idle wywoływane w momencie rozpoczęcia okresu bezczynności aplikacji zdarzenie ApplicationExit powiadomienie o zakończeniu pracy aplikacji właściwość ExecutablePath ścieżka do pliku exe, który zapoczątkował aplikację 11
Klasa Form Reprezentuje główne okna, okna dialogowe oraz okna robocze w aplikacji MDI (Multiple-Document Interface) Hierarchia dziedziczenia: Object MarshalByRefObject Component Control ScrollableControl ContainerControl Form 12
Schemat życia formularza 1. Konstruktor InitializeComponent () utworzenie i zainicjowanie wszystkich kontrolek potomnych dodanych do formularza przy pomocy Form Designer a z MS Visual Studio Control.HandleCreated Control.BindingContextChanged Form.Load Control.VisibleChanged Form.Activated Form.Shown 2. <właściwe działanie formularza> Form.Deactivate Form.FormClosing Form.FormClosed 3. Metoda Dispose (interface IDisposable) miejsce zwalniania wszystkich zasobów używanych przez formularz 4. Destruktor (wywoływany przez Garbage Collector) Zdarzenia przy starcie Zdarzenia przy zamykaniu 13
Rozmiar i pozycja formularza Widoczność Metoda Show() pokazuje formularz Właściwość Visible i zdarzenie VisibleChanged Zdarzenie Shown następuje, kiedy formularz jest po raz pierwszy wyświetlany Właściwości: Bounds, DesktopBounds Rectangle definiujący położenie i rozmiar względem ojca i względem pulpitu Location, DesktopLocation Point zawierający położenie formularza względem ojca i względem pulpitu StartPosition pozycja startowa, np. CenterScreen Width, Height aktualne rozmiary formularza Size, ClientSize struktura Size definiująca rozmiar formularza oraz rozmiar obszaru klienta MinimumSize, MaximumSize ograniczenia na rozmiar AutoSize, AutoSizeMode automatyczne dopasowanie do zawartości WindowState stan formularza (minimized, maximized lub normal) TopMost bool mówiący czy formularz jest zawsze na wierzchu 14
Rozmiar i pozycja formularza c.d. Metody: SetBounds (), SetDesktopBounds (), SetDesktopLocation () CenterToParent (), CenterToScreen () BringToFront () PointToClient (), PointToScreen (), RectangleToClient (), RectangleToScreen () konwersje ze współrzędnych relatywnych do ekranowych, etc. Zdarzenia: ClientSizeChanged, SizeChanged LocationChanged MaximumSizeChanged, MinimumSizeChanged Resize, ResizeBegin, ResizeEnd 15
Wygląd formularza Właściwości: ForeColor, BackColor BackgroundImage, BackgroundImageLayout (Center, None, Stretch, Tile, Zoom) Cursor, Icon Font FormBorderStyle, ShowIcon, ControlBox, MinimizeBox, MaximizeBox, HelpButton, SizeGripStyle ShowInTaskbar, TopLevel Opacity TransparencyKey 16
Wygląd formularza c.d. Metody: ResetBackColor(), ResetForeColor(), ResetFont(), ResetCursor() Zdarzenia: ForeColorChanged, BackColorChanged BackgroundImageChanged, BackgroundImageLayoutChanged FontChanged 17
Mysz Zdarzenia myszy, m.in. MouseMove, MouseDown, MouseUp, MouseClick, MouseDoubleClick Click, DoubleClick Struktura MouseEventArgs { Button - który przycisk został naciśnięty Clicks ile razy przycisk został naciśnięty (np. trzyklik) Delta ile wykonano pokręceń kółkiem myszy Location struktura Point zawierająca położenie myszy X współrzędna x położenia myszy Y współrzędna y położenia myszy MouseEnter, MouseHover, MouseLeave, MouseWheel 18
Pojedyncze kliknięcie myszą - standardowo 1. MouseDown event. 2. Click event. 3. MouseClick event. 4. MouseUp event. 19
Podwójne kliknięcie myszą - standardowo 1. MouseDown event. 2. Click event. 3. MouseClick event. 4. MouseUp event. 5. MouseDown event. 6. DoubleClick event. 7. MouseDoubleClick event. 8. MouseUp event. 20
Zdarzenia myszy dla poszczególnych kontrolek Button, CheckBox, ComboBox oraz RadioButton nie reagują na prawy przycisk, nie ma doubleclick-a TextBox, RichTextBox, ListBox, MaskedTextBox oraz CheckedListBox nie reagują na prawy przycisk ListView reaguje tylko na klikanie na item-ach TreeView reaguje tylko na klikanie na lub po prawej item-ów 21
Klasa Cursor Cursor to właściwość formularza konstruktor wczytuje kursor ze strumienia, pliku, zasobów programu lub systemu standardowe kursory można uzyskać z klasy Cursors,np. Arrow Hand Cross Help WaitCursor Często zmieniamy kursor po wejściu na obszar jakiejś kontrolki, czyli zdarzenie MouseEnter. Gdy aplikacja jest zajęta wyświetlamy WaitCursor, po kliknięciu na helpie kontekstowym kursor Help. 22
Klawiatura Tzw. focus decyduje, która kontrolka otrzyma wejście klawiatury (może być tylko jedna) Metoda Focus() przyznaje focusa kontrolce, z której go wywołano Własności: CanFocus, Focused (czy kontrolka ma focusa), ContainsFocus (czy kontrolka lub jej potomne ma focusa) Enter, Leave (zdarzenia dla kontrolek) Activated, Deactivated (zdarzenia dla formularzy) GotFocus, LostFocus (zdarzenia niskiego poziomu raczej ich unikamy) Microsoft Natural Ergonomic Keyboard 4000 23
Klawiatura Zdarzenia odpowiadające pojedynczemu wciśnięciu klawisza: 1. KeyDown (, KeyEventArgs e) 2. KeyPress (, KeyPressEventArgs: KeyChar) 3. KeyUp (, KeyEventArgs e) KeyEventArgs zawiera m.in. KeyCode, KeyData, oraz Modifiers (Alt, Control, Shift) Typ KeyCode odpowiada klawiszom sensu stricto (np. Keys.Q, Keys.F5, Keys.LShiftKey, zawarte w enum-ie Keys) Typ KeyChar to znak ASCII, który może być uzyskiwany kombinacją klawiszy, np. K = k + SHIFT ś = s + PRAWY_ALT Ś = s + SHIFT + PRAWY_ALT Nie można uzyskać znaków KeyChar dla niektórych klawiszy: TAB, INSERT, DELETE, HOME, END, PAGE UP, PAGE DOWN, F1-F12, ALT, strzałki. 24
Formularze modalne i niemodalne MODALNE Blokują dostęp do okien aplikacji ShowModal () Close () FormClosing FormClosed CancelButton, AcceptButton Zwracają DialogResult NIEMODALNE Nie blokują dostępu do okien aplikacji Show () Close () FormClosing FormClosed 25
Obsługa komunikatów Win32 API private const int HTCAPTION = 0x0002; private const int WM_NCHITTEST = 0x0084; protected override void WndProc (ref Message m) { switch (m.msg) { case WM_NCHITTEST: m.result = (IntPtr)HTCAPTION; break; default: base.wndproc (ref m); break; } } Message: {HWnd, LParam, Msg, Result, WParam} Form.Handle HWND jako typ IntPtr 26
Ustawienia aplikacji Pliki.config do odczytu i zapisu z poziomu aplikacji XML Dynamiczne właściwości Rejestr systemowy <configuration> <appsettings> <add key="welcome"value="hello my user"/> <add key="form1.opacity" value="1"/> </appsettings> </configuration> AppSettingsReader reader = newappsettingsreader (); strings= (string)reader.getvalue ("welcome", typeof (string)); 27
Zasoby Assembly jest zbiorem typów i zasobów dane binarne, pliki tekstowe, dźwiękowe, video, tablice ciągów znaków, ikony, obrazki, pliki XML Wielojęzyczne aplikacje problemy z wielojęzycznym interfejsem użytkownika każdy zasób dodany do assembly może mieć określony swój język i kraj (np. "pl-pl", "en- US", "de-de", "de-at") Są to tzw. satellite assemblies zasoby aplikacji do danego języka 28
Pliki zasobów.txt tekstowy format nazwa/wartość prosty w użyciu dla zasobów tekstowych Language=Polish Next=Następna strona Prev=Poprzednia strona.resx format XML użyteczny dla tekstów i innych typów (np. obrazków).resources format binarny binarny odpowiednik pliku XML tylko w tym formacie zasoby mogą być dołączone do assembly, pozostałe formaty muszą być konwertowane 29
Właściwości Padding i Margin kontrolek 30