Programování v jazyku C# II.
1.kapitola
Obsah • • • •
Windows forms Formuláře Kontrolky Prostředí
2/33
Windows forms • Shrnující název pro množinu tříd umožnující tvorbu grafických uživatelských rozhraní • Součást .NET Frameworku • Součást standardu
3/33
Jmenné prostory • System.Windows.Forms – obsahuje formuláře, kontrolky, dialogy
• System.Drawing – Kreslení, GDI+
• System.Drawing.Imaging – rozšířené možnosti práce s grafikou
• Nutno pridat reference – dělá automaticky vývojové prostředí
4/33
Aplikace • Třída Application poskytuje statické metody a události pro událostmi řízené programování • Application.Run(Form) – zobrazí formulář a zahájí smyčku událostí – blokuje, dokud nedojde k uzavření formuláře • Application.Exit() – ukončí smyčku událostí – zavře všechny okna aplikace • Application.[User|Common]AppData[Path|Registry] – vrátí cesty k adresářum s uživatelskými daty – C:/Documents and Settings/All users/Data aplikací/
// 5/33
Aplikace – příklad
namespace Jcu.Pjc2.Lekce2 { class Program { static void Main (string [] args) { Form form = new Form(); Application.Run (form); } } } 6/33
Třída Form • Třída Form reprezentuje formulář (okno) • Obvykle se dědí od Windows.Forms.Form – přidají se ovládací prvky – přidají se reakce na události
7/33
Třída Form - metody • Show – zobrazí formulář (program pak pokračuje v běhu)
• ShowDialog – zobrazí formulář (ceká dokud se formulář nezavře)
• Close – zavře formulář
• Hide – skryje formulář
• Activate – zobrazí skrytý formulář
8/33
Třída Form - události • Load
– při zobrazení pomocí Show, ShowDialog
• Activated
– když se stane aktivní Activate
• Deactivate
– když se stane neaktivní Hide
• FormClosing
– okno se zavírá – lze zrušit pomocí CancelEvenArgs
• FormClosed
– okno se definitivně zavírá
9/33
Příklad namespace Jcu.Pjc2.Lekce2 { class NonClosingForm : Form { public NonClosingForm() { this.FormClosing += new FormClosingEventHandler (NonClosingForm_FormClosing); } void NonClosingForm_FormClosing (object sender , FormClosingEventArgs e) { e.Cancel = true ; } } class Program { static void Main (string [] args) { NonClosingForm form = new NonClosingForm(); form.ShowDialog(); } } }
10/33
Nemodální formulář • Zobrazí se metodou Show • Vlastní smyčka zpráv – žije si vlastním životem – v aplikaci jich muže být několik
• Muže mít vlastníka – při skrytí, uzavření či aktivaci vlatníka udělá totéž – kreslí se přes vlastníka
11/33
Modální formulář - dialog • Zobrazí se metodou ShowDialog • Dokud není uzavřen, nedovolí uživateli manipulovat s rodičem • Matoda ShowDialog vrací hodnotu – výctový typ DialogResult • Yes, No, Abort . . .
12/33
Modální formulář – předání hodnoty • Nastavení hodnoty v property DialogResult – způsobí uzavření formuláře
• Nastavení hodnoty DialogResult u některého z tlačítek formuláře – není třeba psát obsluhu pro tlačítko – funguje automaticky
13/33
Třída Control • Třída Control je předek všech vizuálních prvku – včetně formuláře
• Umožňuje – – – – –
zobrazení a skrytí nastavení pozice a velikosti vnořování kontrolek reakce na události práci ve vláknech
14/33
Některé kontrolky
15/33
Pozice a velikost • Jednotlivé veličiny – – – – –
pozice horní hrany Top pozice levé hrany Left šířka kontrolky Width výška kontrolky Height dolní a pravá hrana pouze pro čtení (Right, Bottom)
• Velikost a pozice – dvojice výška, šířka Size (SizeF) – dvojice levý, horní Point (PointF)
• Kompletní určení velikosti – struktura Rectangle (RectangleF)
16/33
Velikost kontrolky a klientská oblast • Velikost kontrolky – celková velikost – Width, Height, Size
• Klientská oblast – vnitrek kontrolky bez rámecku, rolovacích lišt, menu . . . – ClientWidth, ClientHeight, ClientSize
17/33
Vnořování kontrolek • Property ControlCollectoin Controls – metoda Add přidá kontrolku – metoda Remove vyjme kontrolku – indexer Controls[int/string] vrátí referenci na kontrolku
• Kontrolka se musí přidat, aby se zobrazila – kontrolky se většinou vytváří jako private členy formuláře (nejsou přístupné zvenku)
18/33
Příklad class ButtonForm : Form { private Button button ; public ButtonForm() { button = new Button(); this.Controls.Add(button); } }
19/33
Chování vnořených kontrolek • Pozice se vztahuje k levému hornímu rohu klientské oblasti rodiče • Vykreslují se vždy pres rodičovskou kontrolku – u sesterských kontrolek záleží na Z-poradí • standardně podle poradí přdání do kolekce kontrolek • BringToFront posune kontrolku nejblíž • SendToBack odsune kontrolku nejdál
• Přebírají některé vlastnosti (ambientní vlastnosti) – barva, font . . .
20/33
Události • Jsou řešeny pomocí delegátů na metody, které danou událost zpracují button.click += new System.EventHandler(buttonClick); void buttonClick (object sender, System.EventArgs e) { this . Close (); }
• Událost je zaslána kontrolkou nad kterou k události došlo (sender) • Odesílatel nezná příjemce • Příjemce zná odesílatele • Další informace jsou uloženy v EventArgs 21/33
Obsluha • Události od více kontrolek muže obsluhovat jediná metoda • V některých případech muže jedna metoda obsluhovat i různé události • Příklad obsluhy button1.Click += new System.EventHandler(button1_Click); button2.Click += new Systém.EventHandler(button1_Click); ... private void button1_Click (object sender, System.EventArgs e) { MessageBox.Show("kliklo se na "+((Button)sender).Text); }
22/33
Klávesnice • KeyDown, KeyUp – argument události obsahuje scan kód klávesy – funguje i pro neznakové klávesy – modifikátory Control, Alt, Shift
• KeyPress – jen pro znakové klávesy – vrací kód znaku
• V případě stisknuté klávesy nastává střídavě události KeyDown a KeyPress, událost KeyUp nastane až při uvolnění klávesy
23/33
Myš • Click a DoubleClick – nemusí být nutně od myší, ale například po stisku klávesy ENTER – pouze informuje, že událost nastala, argument nenese informaci o souřadnicích myši
• MouseClick a MouseDoubleClick – až v .NET 2.0 – podobně jako Click, ale pouze pro myš
• MouseEnter, MouseHover a MouseLeave – pouze informují o události
• MouseMove, MouseDown, MouseUp a MouseWheel – argument události (MouseEventArgs) nese informaci o pozici myši a stavu tlačítek a kolečka
24/33
Vlákna • Čtení či zápis dat kontrolky z jiného vlákna muže způsobit nekonzistenci – v .NET 2.0 vyhodí InvalidOperationException – vláknově bezpečné metody: (Begin/End)Invoke – přístup z jiného vlákna indikuje InvokeRequire
• Synchronní způsob – blokující volání – Invoke(delegate, object[]) – zavolá delegáta vláknem, kterému patří kontrolka – předá pole objektu jako argumenty – vrátí hodnotu, kterou vrátil delegát
25/33
Synchronní způsob public ThreadForm() { button1 = new Button(); thread1 = new Thread(new ThreadStart(CountingThread)); ... } protected void CountingThread() { ... // slozity vypocet SetText (mezivysledek); ... } protected delegate void SetTextDelegate(string text); protected void SetText (string text) { if(button1.InvokeRequired) { SetTextDelegate setText = new SetTextDelegate(SetText); button1.Invoke(setText ,new object[] {text}); }else{ button1.Text = text ; } } 26/33
Asynchronní invoke • BeginInvoke(delegate, object[])
– požádá o zavolání delegáta – není blokující – zařadí požadavek do fronty a pokračuje v běhu – vrátí instanci třídy implementující IAsyncResult
• EndInvoke(IAsyncResult)
– je blokující – vrací návratou hodnotu metody predané v delegátu
27/33
Designér • • •
Wysiwyg editor formulářů Formulář musí být první třída deklarovaná v souboru Úpravy v designéru se projevují v kódu – metoda InitializeComponent – nedoporučuje se upravovat ručně! – v MSVS 05 a SharpDevelop 2 je kód designéru uveden ve zvláštním souboru .Designer.cs
28/33
Program.cs using System; using System.Collections.Generic; using System.Windows.Forms; namespace WindowsApplication { static class Program { [STAThread] static void Main() { Application.EnableVisualStyles(); Application.SetCompatibleTextRenderingDefault(false); Application.Run(new Form1 ()); } } }
29/33
Form1.cs using using using using using using using
System; System.Collections.Generic; System.ComponentModel; System.Data; System.Drawing; System.Text; System.Windows.Forms;
namespace WindowsApplication { public partial class Form1 : Form { public Form1() { InitializeComponent(); } } } 30/33
Form1.Designer.cs namespace WindowsApplication { partial class Form1 { private System.ComponentModel.IContainer components = null ; protected override void Dispose(bool disposing) { if( disposing && ( components != null )) { components.Dispose(); } base.Dispose(disposing); } private void InitializeComponent() { this.button1 = new System.Windows.Forms.Button(); this.SuspendLayout(); // // button1 // this.button1.Location = new System.Drawing.Point (13 , 13); this.button1.Name = " button1 "; this.button1.Size = new System.Drawing.Size (75 , 23); this.button1.TabIndex = 0; this.button1.Text = " button1 "; this.button1.UseVisualStyleBackColor = true; // // Form1 // this.AutoScaleDimensions = new System.Drawing.SizeF (6F, 13F); this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; this.ClientSize = new System.Drawing.Size(292 , 273); this.Controls.Add(this.button1); this.Name = " Form1 "; this.Text = " Form1 "; this.ResumeLayout(false); } private System.Windows.Forms.Button button1; } }
31/33
Form1.cs [Design]
32/33
Konec
Konec
33/33