|
Dobrodružství v C# |
|||||
Jak odkrýt zákoutí jazyka C# |
||||||
Časová náročnost (min): |
Začátečník |
Pokročilý |
Profesionál |
|||
|
|
|
||||
|
Použitý operační systém : Hlavní vývojový
nástroj : Další vývojový software : Jiný software : |
Windows 2000 SP4 Visual C# .NET 2003 Žádný Žádný |
||||
|
Obsah |
Obtížnost |
Čas (min) |
|
|
|
|
||
|
||
|
Přidávání instancí ovládacích prvků na formulář za běhu
aplikace
Integrované prostředí jazyka C# nabízí, podobně jako i další programovací nástroje Visual Studia .NET, vizuální návrhář, pomocí kterého si můžete podobu vyvíjené aplikace upravit podle svých potřeb. Zcela jistě se shodneme na tom, že přítomnost vizuálního návrháře je velice praktickým prvkem integrovaného prostředí, ovšem lze jej použít jenom v rámci režimu návrhu aplikace. Pokud ovšem budete chtít přidávat na plochu formuláře instance ovládacích prvků přímo za běhu programu, budete se muset přiklonit k psaní programového kódu. Jelikož je přidávání a potažmo i odstraňování instancí ovládacích prvků z formuláře aplikace docela běžnou záležitostí, vysvětlíme si, jak tuto úlohu splnit nejrychlejším možným způsobem. Postupujte takto:
//Po aktivaci metody bude na stávající formulář přidána
//instance ovládacího prvku Button.
private void
button1_Click(object sender, System.EventArgs
e)
{
//Vytvoření instance třídy Button a uložení odkazu
//na vzniklou instanci do referenční proměnné Tlačítko_01
Button
Tlačítko_01 = new Button();
//Nastavení návěstí vytvořené instance třídy Button.
Tlačítko_01.Text
= "Spustit aplikaci";
//Nastavení velikosti (šířky a výšky) vytvořené instance
//třídy Button.
Tlačítko_01.Size
= new Size(100, 50);
//Určení pozice (x, y) levého horního rohu vytvořené
instance
//třídy Button (Pozice instance ovládacího prvku je určená
//relativně ve vztahu k formuláři).
Tlačítko_01.Location
= new Point(10, 125);
//Přidání vytvořené instance třídy Button do kolekce
//ovládacích prvků formuláře. Za tímto účelem použijeme
//metodu Add třídy
System.Windows.Forms.Control.ControlCollection.
this.Controls.Add(Tlačítko_01);
}
Novou instanci ovládacího prvku, resp. třídy Button provedeme pomocí přiřazovacího příkazu a operátoru new. Pomineme-li modifikaci různých vlastností vytvořené instance, dojdeme k závěru, že veškerou práci potřebnou pro přidání nové instance na formulář, realizuje finální řádek programového kódu:
this.Controls.Add(Tlačítko_01);
Klíčové slovo this představuje aktuální instanci formuláře, přesněji řečeno aktuální instanci třídy Form1. Přístup ke všem instancím ovládacích prvků, které se na formuláři nacházejí, poskytuje kolekce instancí s názvem Controls. Použijeme-li metodu Add s názvem instance, kterou chceme přidat na plochu aktivního formuláře, bude tato instance přidána právě do kolekce instancí Controls. Připomeňme, že přidání instance do kolekce Controls tuto instanci na formuláři také zviditelní (není tedy nutné dodatečně nastavovat vlastnosti Visible vytvořené instance na hodnotu True).
//Vytvoření asociace mezi událostí Click vytvořené instance
//třídy Button a jejím zpracovatelem.
Tlačítko_01.Click
+=new EventHandler(Tlačítko_01_Click);
//Programová konstrukce zpracovatele události Tlačítko_01_Click
private void
Tlačítko_01_Click(object sender, EventArgs e)
{
//Vytvoření instance třídy Process, která se nachází v
jmenném
//prostoru System.Diagnostics.
System.Diagnostics.Process
Aplikace_01 =
new System.Diagnostics.Process();
//Specifikace názvu aplikace, kterou budeme chtít spustit.
//Za tímto účelem použijeme vlastnost FileName.
Aplikace_01.StartInfo.FileName
= "Notepad";
//Zavoláním metody Start spustíme vybranou aplikaci.
Aplikace_01.Start();
}
Překrytí metody OnPaint formuláře
Metoda OnPaint reaguje na událost Paint, ke které dojde vždy v okamžiku překreslení formuláře. Pokud překryjeme metodu OnPaint formuláře, budeme moci zajistit, aby se při každém překreslení plochy formuláře uskutečnil jistý fragment programového kódu. Ačkoliv lze do překryté metody OnPaint umístit jakékoliv platné programové instrukce, nejčastěji se tělo této překryté metody používá pro modifikaci grafické reprezentace formuláře jako takového. Jak jistě víte, implicitně je barva pozadí formuláře šedá, ovšem pokud překryjeme metodu OnPaint tohoto formuláře, můžeme sami určit, jakou barvu pozadí má formulář mít.
Pro překrytí metody OnPaint formuláře Form1 udělejte následovní:
Tip |
|
|
Dialogové okno Class View můžete zobrazit i
prostřednictvím klávesové zkratky CTRL+SHIFT+C. Okno Class View sdílí společný
region s dalšími okny (např. Solution Explorer či Resource View). |
·
Název projektu
·
Název jmenného prostoru
·
Form1
·
Bases and Interfaces
·
Form
Obr. 1 – Proces překrytí metody OnPaint
formuláře
protected
override void
OnPaint(PaintEventArgs e)
{
// TODO: Add Form1.OnPaint implementation
base.OnPaint
(e);
}
protected override void
OnPaint(PaintEventArgs e)
{
//Vytvoření nové instance struktury
System.Drawing.Rectangle.
Rectangle
GObdélník = new
Rectangle(new Point(0, 0),
new Size(this.Width, this.Height));
//Vytvoření nového grafického štětce, který je sestaven
//ze třídy LinearGradientBrush.
LinearGradientBrush
GŠtětec = new
LinearGradientBrush(GObdélník,
Color.Red, Color.Orange, LinearGradientMode.ForwardDiagonal);
//Deklarace referenční proměnné GObjekt,
do které je uložen
//odkaz na objekt Graphics, jenž představuje plochu, na
kterou
//se bude kreslit. V našem případě jde o plochu aktuální
instance
//třídy Form1.
Graphics
GObjekt = e.Graphics;
//Aplikace metody FillRectangle,
která má na starosti práce
//spojené s vyplněním plochy aktuální instance třídy Form1
//gradientní výplní.
GObjekt.FillRectangle(GŠtětec, GObdélník);
//Uvolnění zdrojů, které byly alokovány příslušnými
grafickými
//objekty.
GObjekt.Dispose();
GŠtětec.Dispose();
//Volání metody OnPaint bázové třídy. Bázovou třídou
//je třída Control.
base.OnPaint (e);
}
Obr. 2 – Změna barvy pozadí
formuláře pomocí překrytí metody OnPaint
Strukturovaná správa chyb v praxi
Pro mnoho programátorů představuje problematika správy a ošetřování chyb v jejich programech téma, které by vystačilo na opravdu dlouhou diskusi. Je nepopiratelné, že chyby se v softwarových aplikacích vyskytovaly, vyskytují a s velikou pravděpodobností se také vyskytovat budou v i budoucích etapách vývoje programování. Přestože je tato teze ryzí skutečností, snad na všech frontech se objevují zástupy programátorů, kteří se pouštějí do boje s virtuálními chybami. Cíl je jasný: Snížit počet objevitelných chyb na takovou míru, která by byla přínosná, a to jak pro programátora, tak pro samotného finálního uživatele. Ačkoliv nemáme v tuto chvíli dostatečný prostor na podrobnou charakteristiku filozofie chyb, jejich klasifikaci a specifikaci, ukážeme si, jaké nové zbraně pro boj s počítačovými štěnicemi nabízí platforma .NET Framework a potažmo i jazyk C#.
Zaklínadlem dnešních dnů se v rámci programování na .NET úrovni stává takzvaná strukturovaná správa chyb. Ihned ze začátku je zapotřebí zmínit skutečnost, že správa chyb je unifikovaná a pečlivě implementovaná do všech programovacích jazyků pro prostředí .NET Framework. Tedy nejenom C#, ale také Visual Basic .NET, Visual J# a řízené C++ obsahují mechanizmy, které dovolují relativně snadné a současně flexibilní „odchytávání“ chyb v softwarových aplikacích. Společná chybová politika nabírá na významu zejména při programování ve více programovacích jazycích: Je například možné generovat chybovou výjimku z aplikace napsané v C# a posléze „zachytit“ tuto výjimku třeba v řízeném C++ nebo ve Visual Basicu .NET.
Po formální stránce je strukturovaná správa chyb v C# prezentována programovou konstrukcí try-catch-finally. Obecně lze při práci s chybami postupovat pomocí následující struktury:
Poznámka |
|
|
Počet bloků catch
však zvyčejně závisí od stylu, jakým programátor přistupuje k procesu
ošetřování chyb. Tudíž lze vytvořit jenom jeden generický blok catch a
všechny chybové výjimky, které budou generovány, zpracovávat podle jednotného
scénáře v rámci jednoho bloku catch. V praxi se ovšem určitě
častěji střetnete s přítomností většího počtu catch bloků. V tomto
případě může každý blok zachytávat jenom specifický typ chybových výjimek. |
V následující programové ukázce si předvedeme, jak použít strukturovanou správu chyb v praxi. Vytvoříme třídu, instance které budou sloužit jako lokální prohlížeče obrázkových souborů. Třída bude obsahovat metodu ZačítProhlížení, které bude jako argument předáno pole textových řetězců, představujících cesty ke grafickým souborům, určeným pro prohlížení. Jestliže se na lokálním pevném disku nebudou nacházet soubory s daným jménem, dojde k vygenerování chybové výjimky. Tato výjimka bude odchycena v příslušném bloku Catch a také patřičně ošetřena. Postupujte takto:
using System;
using System.Drawing;
using System.Windows.Forms;
namespace cs_1_04_dob_01
{
/// <summary>
/// Třída slouží pro prohlížení grafických obrázků.
/// </summary>
public class ProhlížečObrázků
{
public
ProhlížečObrázků()
{
//Tělo
konstruktoru.
}
//Definice
metody ZačítProhlížení. Všimněte si, že metoda
//pracuje s
polem textových řetězců.
public void ZačítProhlížení(string[]
pole)
{
//Instantiace
objektů tříd Form a PictureBox.
Form frm = new Form();
PictureBox pict
= new PictureBox();
//Začátek
strukturované správy chyb je identifikován
//klíčovým
slovem try, za kterým se nachází blok programového
//kódu,
jenž je ohraničen složenými závorkami. Veškerý kód,
//který
se nachází uvnitř bloku try, je podroben strukturované
//správě
chyb. Dojde-li v kódu v tomto bloku k chybě, bude
//generována
chybová výjimka.
try
{
frm.Size = new Size(400, 300);
frm.ControlBox
= false;
frm.FormBorderStyle =
FormBorderStyle.FixedDialog;
pict.Location
= new Point(0,0);
pict.Size
= new Size(frm.Width, frm.Height);
pict.SizeMode
= PictureBoxSizeMode.StretchImage;
frm.Controls.Add(pict);
frm.Show();
//Obrázky
jsou načteny v cyklu, přičemž uživatel má
//k
dispozici přesně dvě vteřiny, aby si obrázek prohlédl.
//Po
uplynutí stanoveného časového intervalu je zobrazen
//další
dostupný obrázek.
for
(byte a = 0; a <= pole.GetUpperBound(0);
a++)
{
Image obr =
Image.FromFile(pole[a]);
pict.Image
= obr;
pict.Refresh();
System.Threading.Thread.Sleep(2000);
Application.DoEvents();
}
//Konec
bloku try.
}
//První
blok catch. Tento blok bude zapojen do činnosti
//v
případě, jestliže bude v bloku try generována výjimka
//typu
System.IO.FileNotFoundException. Abychom mohli využít
//informace,
které si výjimka s sebou nese, deklarujeme
//referenční
proměnnou x1.
catch
(System.IO.FileNotFoundException x1)
{
//Výjimka
FileNotFoundException vzniká v okamžiku, kdy
//se
na disku nenachází příslušný soubor. V tomto případě
//zobrazíme
dialogové okno se zprávou, která bude uživateli
//oznamovat
vzniklou chybovou situaci společně s názvem
//chybějícího
souboru.
MessageBox.Show("Soubor
" + x1.Message + " nebyl nalezen.",
"Zpráva o chybě
za běhu programu",
MessageBoxButtons.OK,
MessageBoxIcon.Error);
}//Konec
prvního bloku catch.
//Druhý
blok catch. Zde budou zpracovávány všechny ostatní
//výjimky,
kromě té, se kterou se pracuje v prvním bloku catch.
catch
(System.Exception)
{
//Ošetření
všech ostatních výjimek, ke kterým může dojít.
}//Konec
druhého bloku catch.
//Začátek
bloku finally. Zde vložíme všechny příkazy, kterých
//provedení
není závislé na otázce, zdali došlo k chybě či nikoliv.
finally
{
frm.Close();
}//Konec
bloku finally.
}
}
}
//Vytvoření nové instance třídy ProhlížečObrázků.
ProhlížečObrázků
x = new ProhlížečObrázků();
//Deklarace pole, které může uchovat čtyři textové řetězce.
string[] pole_x = new
string[4];
//Naplnění jednotlivých prvků pole textovými řetězci.
//Tyto řetězce představují plně kvalifikované názvy
//k cílovým souborům s grafickými daty. Jména souborů jsou
//Obr1.png, Obr2.png atd., přičemž všechny soubory jsou
//uloženy na lokálním disku d.
for(byte a = 0; a
< 4; a++)
pole_x[a] = "d:\\obr"
+ (a+1) + ".png";
//Aktivace metody ZačítProhlížení vytvořené instance.
//Metodě je jako argument odevzdáno pole textových řetězců.
x.ZačítProhlížení(pole_x);
Volání metody bázové třídy z odvozené třídy
Aktivace metody bázové třídy z podtřídy je velmi užitečná technika, pomocí které můžete ve vhodné chvíli zavolat metodu bázové třídy, a to přímo z kódu odvozené třídy. Každá odvozená třída může využívat všech dovedností, které nabízí její bázová třída, a proto není ani nejmenším problémem aktivace příslušných metod bázové třídy z prostředí odvozené třídy. Abychom mohli zavolat metodu bázové třídy, použijeme v C# klíčové slovo base, za kterým následuje tečkový operátor (.) a název metody bázové třídy, kterou chceme aktivovat:
base.CílováMetodaBázovéTřídy
Více informací přináší následující programová ukázka (je uveden výpis celé třídy):
using System;
using System.Diagnostics;
using System.Windows.Forms;
namespace cs_1_04_dob_01
{
//Definice třídy
A1.
public class A1
{
//Definice
veřejné virtuální metody.
public
virtual void
SpustitPoštovníhoKlienta()
{
//Aktivace
metody Start třídy Process z jmenného prostoru
//System.Diagnostics.
Výsledkem práce metody je spuštění
//poštovního
klienta.
Process.Start("mailto:hanja@stonline.sk");
}
}
//Definice třídy
B1 jako podtřídy bázové třídy A1.
public class B1 : A1
{
//Definice
metody, která překrývá metodu bázové třídy.
//Z této
překryté metody bude pomocí klíčového slova base
//volána
metoda bázové třídy.
public
override void
SpustitPoštovníhoKlienta()
{
//Minimalizace
aktivní instance třídy Form.
Form.ActiveForm.WindowState = FormWindowState.Minimized;
//Aktivace
metody bázové třídy pomocí klíčového slova base,
//tečkového
operátoru a názvu cílové metody.
base.SpustitPoštovníhoKlienta();
}
}
}
Výpis kódu pracuje se dvěma třídami: A1 a B1. Třída A1 obsahuje veřejnou virtuální metodu SpustitPoštovníhoKlienta. Je-li tato metoda aktivována, dochází k nastartování aplikace, která je na cílovém počítačovém systému nakonfigurována jako poštovní klient. Třída B1 je odvozená od třídy A1, přičemž v překryté variantě metody SpustitPoštovníhoKlienta je volána metoda bázové třídy A1.
|
Právě jste dočetli Dobrodružství
v C#. Pokud se chcete
dozvědět více informací o programování v C#, neváhejte a navštivte i další
součástí rubriky Visual C# .NET: Začínáme s jazykem C# - Seriál je určen především zájemcům o studium
základních a pokročilých programovacích prvků v jazyku C#. Jestliže se
chcete začít učit programovat právě v jazyku C#, nebo patříte-li
k programátorům, kteří přecházejí z prostředí jiného programovacího
jazyka, naleznete v jednotlivých dílech seriálu vše, co budete
potřebovat ke snadnému zvládnutí jazyka C#.
Otázky a odpovědi
–
Trápí-li vás nějaký programátorský problém, na jehož řešení ne a ne přijít,
pak jste na správném místě. U čtenářů oblíbená forma řešení potíží stylem
otázek a odpovědí si našla svůj prostor i v naší rubrice. Máte-li
problém, s kterým nevíte hnout, pošlete jeho popis autorovi rubriky, jenž
vyvine maximální úsilí pro rychlé vyřešení jakékoli programátorské záhady. |
|
Autor: Ján Hanák |