Spolu s Visual Studiem je dodávána spousta ovládacích prvků, jako jsou Button, Listbox, Label a další, které je možné použít pro vytváření GUI aplikace. Co však dělat, pokud si ze spousty možností, které jsou ve Visual Studiu standardně, nevyberete, protože ani jeden z nich neposkytuje funkčnost, specifickou pro Vaši aplikaci? V podstatě máte dvě možnosti - zkusit najít na internetu Vám vyhovující komponentu, anebo si vytvořit vlastní ovládací prvek. V tomto článku se dozvíte, jak na druhou možnost.
2. Custom Controls
Custom Controls jsou na rozdíl od kompozitních - skládaných o trochu složitější. Je to z toho důvodu, že musíme u těchto prvků řídit samotné vykreslování. To nám zároveň dává velkou možnosti, vytvořit si téměř libovolnou komponentu.
Pro naše demonstrační účely si opět vytvoříme ovládací prvek, který bude reprezentovat minutku pro odpočet času. Grafická podoba zbývajícího času bude zobrazena jako přibývající nebo ubývající "koláč". Struktura celého prvku bude po stránce zdrojového kódu stejná jako u komponenty SkladanaMinutka. Pouze nebudeme potřeboval některé části.
V Solution Exporeru klikněte pravým tlačítkem a zvolte Add -> New Item -> Custom Control -> Add. Tím dojde k přídání nové třídy, odvozené od třídy Control. Uvnitř je již vygenerován event handler pro událost Paint. Pojmenujme si nový prvek tím, že se přepneme do pohledu Design a v Properties Window nastavíme vlastnost Name na NovaMinutka.
Protože bude tato komponenta opět využívat Timer, přidejme jej tedy na plochu ovládacího prvku.
Jako minule, začněme vytvořením vnitřních proměnných:
// interval pro Timer - 1s
private int _interval = 1000;
// odpočítávaný čas
private int _limit = 1;
// hlášení zobrazované po vypršení času
private string _alertMessage = "";
// přibývání nebo ubývání "koláče"
private bool _reversion = false;
// aktuální čas
private int _current = 0;
// úhel vykrojení "koláče"
private int _angle = 0;
|
V konstruktoru nastavíme interval pro Timer:
public NovaMinutka()
{
InitializeComponent();
timer1.Interval = _interval;
}
|
Nyní potřebujeme vlastnosti, pro nastavování prvku:
[Category("Behavior")]
[Description("Nastaví časový limit")]
[DisplayName("TimeLimit")]
public int Limit
{
get
{
return _limit;
}
set
{
// musí být větší než nula z důvodu vykreslování prvku
// viz. event handler OnPaint
if (value == 0)
{
MessageBox.Show("Musí být větší než nula");
}
else
{
_limit = value;
}
}
}
[Category("Behavior")]
[Description("Nastaví hlášení pri vypršení limitu")]
[DisplayName("AlertMessage")]
public string Alert
{
get
{
return _alertMessage;
}
set
{
_alertMessage = value;
}
}
[Category("Behavior")]
[Description("Nastaví způsob zobrazení odpočtu")]
[DisplayName("Reversion")]
public bool Reversion
{
get
{
return _reversion;
}
set
{
_reversion = value;
}
}
|
V tuto chvíli následuje veřejná metoda pro spuštění minutky:
public void Start()
{
// vynulování aktuálního času
_current = 0;
// vynulování vykrojení "koláče"
_angle = 0;
// vynucení překreslení prvku
Refresh();
// spuštění Timeru
timer1.Start();
}
|
V pohledu Design se v
Properties Window přepneme do zobrazení událostí a dvojklikem necháme vytvořit event handler
Tick pro prvek Timer.
Do tohoto handleru vložíme:
private void timer1_Tick(object sender, EventArgs e)
{
// byl dosažen konec odpočtu?
if (_current != _limit)
{
// aktuální čas
_current++;
// vynucení překreslení
this.Refresh();
}
else
{
timer1.Stop();
// jestliže bylo nastavení hlášení, zobrazí jej
if (!string.IsNullOrEmpty(_alertMessage))
MessageBox.Show(_alertMessage, "Minutka",
MessageBoxButtons.OK, MessageBoxIcon.Information);
}
}
|
Na závěr potřebujeme zajistit vykreslení prvku. K tomu použijeme již vygenerovaný handler OnPaint, který rozšíříme:
protected override void OnPaint(PaintEventArgs pe)
{
base.OnPaint(pe);
_angle = _reversion ? (360 / _limit) * (_limit - _current) : (360 / _limit) * _current;
pe.Graphics.FillPie(new SolidBrush(Color.Salmon),
new Rectangle(2, 2, this.Width - 5, this.Height - 5),
-90, _angle);
pe.Graphics.DrawEllipse(new Pen(new SolidBrush(Color.Salmon)),
new Rectangle(0, 0, this.Width - 1, this.Height - 1));
}
|
Tím máme celou komponentou hotovou. Opět můžeme ještě nastavit ikonu komponenty:
namespace MyControls
{
[ToolboxBitmap(typeof(Timer))]
public partial class NovaMinutka : Control
{
// interval pro Timer - 1s
private int _interval = 1000;
// odpočítávaný čas
private int _limit = 1;
|
A to je už opravdu vše. Jak vidíte vytváření vlastních ovládacích prvků není vůbec nic těžkého a zvládne jej každý, znající základy .NET Frameworku.