Dialgy pr kmunikaci s uživatelem nastavení většíh mnžství hdnt najednu hstí vládací prvky speciální případ kna (z phledu OS Windws) v.net shdné s běžným frmulářem základní vlastnsti: zpravidla neměnná velikst implicitní reakce na klávesy (ENTER, ESC) mdální x nemdální dialg chvání vůči vlastníkvi: aplikačně mdální zákaz vlastníka (většina dialgů) systémvě mdální vždy na vrchu úklvě mdální (task mdal) zákaz všech tp-level ken danéh vlákna Vlastní dialgy Vytvření v.net shdné s běžným frmulářem mžnsti prgramvě Frm dialg = new Frm(); vzhled nepůjde vytvřit v návrháři přes návrhář VS2005 menu Prject Add new Item Vzhled kna bvykle neměnná velikst, nezbrazuje se v liště úlh dialg.frmbrderstyle = FrmBrderStyle.FixedDialg; dialg.maximizebx = false; dialg.minimizebx = false; dialg.shwintaskbar = false; spuštění (zbrazení): mdální: dialg.shw() nemdální: dialg.shwmdal() 1
Přidání vládacích prvků jasné, viz cvičení Kntrla zadaných hdnt je ta hdnta > 0?, je t telefnní čísl? ruční při zavření dialgu něc špatně = strnvání zavření dialgu (událst Frm.Clsing) viz min. přednáška autmatická událst Validating zděděna z Cntrl vyvlá se při puštění prvku (ztrátě fkusu) pdrbněji viz cvičení Vstup a výstup dat viz cvičení Uknčení dialgu Obvyklé mžnsti: Stiskem OK uživatel chce nastavené hdnty pužít (prvést akci) Stiskem Strn nechce Něc jinéh (velmi nebvyklé) Nutn přidat tlačítka OK a Strn Rzeznání způsbu uknčení metda ShwMdal() vrací DialgResult enum DialgResult // Tlačítka: Abrt, // Zrušit Cancel, // Strn Ignre, // Ignrvat N, // Ne u MessageBx Nne, OK, // OK Retry, // Znvu Yes // An u MessageBx Třída Frm Vlastnst DialgResult DialgResult před uknčením naplnit pdle tlačítka (OK/Strn) Defaultní hdnta Nne private vid buttnok_click(bject sender, EventArgs e) this.dialgresult = DialgResult.OK; this.clse(); // implicitne nastavi DialgResult na DialgResult.Cancel private vid buttnstrn_click(bject sender, EventArgs e) this.clse(); 2
V nadřazeném frmuláři kntrla typu uknčení a akce: private vid buttnnastavdata_click(bject sender, EventArgs e) NastavDataDialg dialg = new NastavDataDialg(); DialgResult dr = dialg.shwdialg(); if (dr == DialgResult.OK) // Akce, vyzvednutí dat label1.text = "OK"; else // bvykle nic neděláme label1.text = "Strn"; Nedstatky ručníh nastavení DialgResult v dialgu dle tlačítka nefunguje výchzí chvání při stisku kláves ENTER (= tlačítk OK) a ESC (= tlačítk Cancel) Řešení Frm Vlastnsti: AcceptButtn přiřadit referenci na tlačítk OK CancelButtn na Cancel public NastavDataDialg() InitializeCmpnent(); this.acceptbuttn = this.buttnok; this.cancelbuttn = this.buttnstrn; Běžné dialgy lze udělat phdlně i v návrháři v tmt případě událsti tlačítek není nutné vůbec bsluhvat tlačítka získají autmaticky pžadvanu funkčnst uživatel je zná a čekává v.net předpřipraveny jak třídy princip práce stejný jak u nrmálníh dialgu: puze není nutn vytvářet Dialgy: ClrDialg OpenFileDialg SaveFileDialg FlderBrwserDialg FntDialg PageSetupDialg PrintDialg PrintPreviewDialg 3
Příklad OpenFileDialg Metdy DialgResult ShwDialg() zbrazí dialg Vlastnsti: string FileName (Get, Set) cesta + jmén subru ( Název subru: ) string Filter (Get, Set) filtr pr výběr subrů ( Subry typu: ) Příklad: "Text files (*.txt) *.txt All files (*.*) *.*" string Title (Get, Set) titulek dialgu (Otevřít) string InitialDirectry (Get, Set) Adresář p zbrazení dialgu Lze vybrat více subrů najednu Vlastnsti: bl Multiselect (Get, Set) pvlení výběru více subrů string[] FileNames (Get, Set) cesty + jména subrů, Length = pčet vybraných subrů Reakce na výběr neexistujícíh subru (uživatel zadá jmén ručně), kntrla: ručně přes System.IO.File.Exists() autmaticky (zbrazí varvání) bl CheckFileExists (defaultně true) Příklad: OpenFileDialg pf = new OpenFileDialg(); pf.filter = "Textvé subry (*.txt) *.txt Všechny subry (*.*) *.*"; pf.initialdirectry = Envirnment.GetFlderPath(Envirnment.SpecialFlder.MyDcuments); // cesta k adresari "Dkumenty" DialgResult dr = pf.shwdialg(); if (dr == DialgResult.OK) 4
// uzivatel stiskl OK, neb Enter // vyzvedneme si jmen + cestu k subru string subr = pf.filename; Grafika v.net = vytváření grafických brazců na frmulářích Filsfie kreslení ve Windws GDI Aplikace Device Cntext Device Driver GDI = Graphics Driver Interface = API pr kreslení Kreslení je nezávislé na výstupním zařízení: Obrazvka Paměť Tiskárna GDI+ = vylepšené GDI pr Windws XP a nvější Přístupné v.net přes třídy ve jmenných prstrech: System.Drawing System.Drawing.Drawing2D System.Drawing.Imaging System.Drawing.Text System.Drawing.Printing Chci kreslit = nutn pžádat Windws Device Cntext (DC, kntext zařízení) Windws vytvří dle mžnstí zařízení (rzměry, rzlišení, barevná hlubka, mžnsti vladače ) DC v.net reprezentván bjektem třídy System.Drawing.Graphics = virtuální plátn Objekt třídy Graphics nelze libvlně vytvřit nutn jej získat, mžnsti: Vláním Cntrl.CreateGraphics() přímé kreslení Obsluhu událsti Cntrl.Paint Princip 2D kreslení v.net: Grafická primitiva: Clr, Pen (štětec), Brush (výplň), Clr (barvy), Rectangle (bdélník pzice a tvar), Nástrje pr kreslení: DrawLine(), DrawRectangle(), DrawString(), FillRectangle() Pužívají grafická primitiva 5
Přímé kreslení Pstup: Získání DC Kreslení Navrácení zpět DC Windws (nutné!!!) Příklad: private vid buttnkresli_click(bject sender, EventArgs e) Graphics g = this.creategraphics(); // 1) Graphics získán d Frm - this try finally Brush b = new SlidBrush(Clr.Red); g.fillrectangle(b, 0, 0, 50, 50); g.dispse(); // 2) puziti Lepší: private vid buttnkresli_click(bject sender, EventArgs e) using (Graphics g = this.creategraphics()) Brush b = new SlidBrush(Clr.Red); g.fillrectangle(b, 0, 0, 50, 50); Dispse() zajistí příkazu using Výsledek: // 3) vraceni, nutne Ale pzr: 6
Činnst Windws při kresleni Skrytí (časti) kna nutn jej pět bnvit: Ovládací prvky, Titulkvý pruh, bnví Windws Grafické bjekty z Graphics musí bnvit prgramátr Událst Paint zapuzdřuje zprávu WM_PAINT zaslána aplikaci při pžadavku Windws na bnvu vzhledu aplikace Kreslení v událsti Paint Graphics je již vytvřen private vid Frm1_Paint(bject sender, PaintEventArgs e) Graphics g = e.graphics; Brush b = new SlidBrush(Clr.Red); g.fillrectangle(b, 0, 0, 50, 50); Žádné Dispse() Graphics nebyl vytvřen námi!!! Prblém vykreslen ihned p startu, nikli na stisk tlačítka. Řešení: public partial class Frm1 : Frm public Frm1() InitializeCmpnent(); bl vykreslit = false; private vid buttnkresli_click(bject sender, EventArgs e) vykreslit = true; this.invalidate(true); // reakce Win zaslu WM_Paint // true budu překresleny i pdřízené prvky private vid Frm1_Paint(bject sender, PaintEventArgs e) if (vykreslit) Graphics g = e.graphics; Brush b = new SlidBrush(Clr.Red); g.fillrectangle(b, 0, 0, 50, 50); Obsluhujeme Paint vždy th prvku, na který chceme kreslit!!! Kreslení na tlačítk = Paint tlačítka, nikli Frm1 Cíle kreslení Objekt Graphics dvlí kreslit jen na Client Area prvku, d kteréh byl získán 7
Kreslit lze na ckli Graphics pchází z Cntrl (= křen hierarchie prvků GUI) private vid buttnkresli_paint(bject sender, PaintEventArgs e) Graphics g = e.graphics; // g patří buttnkresli!!! Pen p = new Pen(Clr.Blue, 3); g.drawellipse(p, 0, 0, 70, 40); Činnst Windws při kresleni II Prblém při změně veliksti kna Windws překreslí jen t, c musí Řešení: public Frm1() InitializeCmpnent(); this.setstyle(cntrlstyles.resizeredraw, true); // Windws překreslí při změně veliksti vše Prblém blikání brazu: Velký pčet bjektů k vykreslvání braz bliká Řešení = tzv. Duble bufferring Vykreslení brazu nejprve d paměti Celý braz najednu na brazvku public Frm1() InitializeCmpnent(); // duble buffering this.dublebuffered = true; this.setstyle(cntrlstyles.allpaintinginwmpaint, true); 8
this.setstyle(cntrlstyles.optimizeddublebuffer, true); this.setstyle(cntrlstyles.userpaint, true); 9