17. díl - Vlastní ovládací prvky v C# .NET

C# .NET Windows Forms Vlastní ovládací prvky v C# .NET

V předchozích 4 dílech jsme pracovali se základními ovládacími prvky, které nabízí sám .NET Framework. Asi však chápete, že nejsou všemocné a zkrátka a dobře nestačí na všechno. Dnes se podíváme na tvorbu vlastních ovládacích prvků.

Představme si, že potřebujeme udělat progressbar, který se bude načítat od zadu. Výsledek bude vypadat asi nějak takto:

Progressbar načítaný naopak

ProgresBar bude tedy celkem obyčejný, jen se bude načítat zprava doleva.

Přidání prvku do projektu

V Solution Exploreru klikněte pravým tlačítkem myši na projekt a zvolte Add New Item. V dialogu Add New Item vyberte šablonu User Control, ovládací prvek pojmenujte MujProgressBar.cs.

Add New Item – User Control

Otevře se vám návrhář ovládacího prvku, do prvku vložte PictureBox. Celému prvku nastavte v okně Properties vlastnosti width na 200 a height na 25. PicureBoxu nastavte location na 0;0, width na 200, height na 25 a Anchr na Top, Left, Bottom a Right, tedy všechny strany. Timto zajistíte, že ovládací prvek bude mít rozměry 200×25 a při zvětšení se rozšíří i PictureBox na který budeme později postup vykreslovat.

V Solution Exploreru klikněte na MujOvladaciPrvek­.cs, a potom klikněte na Show Code. Přidejte vlastnosti MaxValue a Value typu int. Dále ještě vytvořte privátní MinValue, kterému nastavte hodnotu na 0. V setteru vlastností zavolejte ProgressBar_Pa­int(), jako první a druhý parametr mu předejte null. Tato metoda zatím neexistuje, později ji přidáme.

private int _value = 0;
public int Value
{
        get { return _value; }
        set { _value = value;  ProgressBar_Paint(null, null); }
}
private int minValue = 0;
private int _maxValue = 100;
public int maxValue
{
        get { return _maxValue; }
        set { _maxValue = value; ProgressBar_Paint(null, null); }
}

Dále přidejte metody Increment a Decrement, bez parametrů. Tyto metody pak přetižte, aby příjmaly jeden parametr – Value. V těchto metodách budeme inkrementovat (či dekrementovat) hodnotu progressbaru. Kód metodu bude následující:

public void Increment(int Value)
{
        if (this.Value + Value > maxValue)
                throw new ArgumentOutOfRangeException("Hodnota překročila maximum");
        this.Value += Value;

}

public void Increment()
{
        if (this.Value + 1 > maxValue)
                throw new ArgumentOutOfRangeException("Hodnota překročila maximum");
        this.Value += Value;
}

public void Decrement(int Value)
{
        if (this.Value - Value < minValue)
                throw new ArgumentOutOfRangeException("Hodnota klesla pod minimum");
        this.Value -= Value;
}

public void Decrement()
{
        if (this.Value - 1 < minValue)
                throw new ArgumentOutOfRangeException("Hodnota klesla pod minimum");
        this.Value -= 1;
}

V každé z těchto metod ověřujeme, jestli hodnota nepřesáhla maximum nebo minimum, pokud ano, vyhodíme neošetřenou výjimku ArugumentOutO­frangeExcepti­on. Pokud nová hodnota bude validní tak ji přičteme nebo odečteme.

Nyní ještě musím progressbar překreslit, přesuneme se do okna návrháře. V okně properties se přesuneme na události a k události Paint přidáme novou obsluhu ProgressBar_Paint. Přesuňte se do editoru kód a do obsluhy ProgressBar_Paint přidejte následující kód:

Graphics g = pictureBox1.CreateGraphics();
double vykreslovanaDelka = (double)this.Value * 100.0 / (double)maxValue / 100.0 * (double)this.Width;
g.Clear(Color.Green);
g.FillRectangle(Brushes.White, new Rectangle(0, 0, this.Width - int.Parse(vykreslovanaDelka.ToString()), 25));

Na prvním řádku deklarujeme grafiku PictureBoxu, na tuto grafiku budeme vykreslovat, pak vypočítáme pomocí jednoduché trojčlenky velikost (v px), kterou musíme vykreslit a pak ji vykreslíme od konce.

Nyní se přesuňte do fomuláře. Dolů na formulář přidejte 2 tlačítka a jeden NumericUpDown. Tlačítkům dejte text + a – a numericUpDown neměňte.

Tlačítka pro inkrementaci a dekrementaci

Implementace prvku

Z toolboxu

Všimněte si, že v okně toolboxu přibyla nová skupina <nazev projektu> Components. V této skupině se nachází pointer, který se automaticky přidává do každé skupiny a Váš progressbar. S tímto progress barem můžete nyní zacházet jako s každým jiným ovládacím prvkem. Přetáhněte si nový progressBar do formuláře. Nyní se ve vašem formuláři nachází nový ovládací prvek.

Z kódu

Přesuňte se do kódu a ve formuláři si vytvořte priátní prog typu MujProgressBar a hned ho inicializujte. V konstruktoru mu nastavte Location na 12;43 a přidejte ho do formuláře.

MujProgressBar prog = new MujProgressBar();
public Form1()
{
        InitializeComponent();
        prog.Location = new Point(12, 43);
        Controls.Add(prog);
}

Ještě přidejte obsluhy události pro oba tlačítka, která nám budou inkrementovat a dekrementovat progressbar.

private void button1_Click(object sender, EventArgs e)
{
        try
        {
                if (numericUpDown1.Value > 1) {
                        prog.Increment(int.Parse(numericUpDown1.Value.ToString()));
                        mujProgressBar1.Increment(int.Parse(numericUpDown1.Value.ToString()));
                } else {
                        prog.Increment();
                        mujProgressBar1.Increment();
                }
        }
        catch (ArgumentOutOfRangeException ex)
        {
                MessageBox.Show(ex.Message);
        }

}

private void button2_Click(object sender, EventArgs e)
{
        try
        {
                if (numericUpDown1.Value > 1)
                {
                        prog.Decrement(int.Parse(numericUpDown1.Value.ToString()));
                        mujProgressBar1.Decrement(int.Parse(numericUpDown1.Value.ToString()));
                }
                else
                {
                        prog.Decrement();
                        mujProgressBar1.Decrement();
                }
        }
        catch (ArgumentOutOfRangeException ex)
        {
                MessageBox.Show(ex.Message);
        }
}

Program si vyzkoušejte, že funguje a progressbar se opravdu načítá od zadu.

Vlastní uživatelské prvky se hodí pro specifické věci, dělat si vlastní TextBox je asi nesmysl. Je to samé jako vynálezat znova kolo. Ale pokud opravdu potřebujete nějaký prvek pro specifický účel, je to určitě vhodná volba.

V tomto dílu jste se naučili vytvářet vlastní ovládací prvky a naučili jste se je implementovat do programu.


 

Stáhnout

Staženo 359x (92.41 kB)
Aplikace je včetně zdrojových kódů v jazyce C#

 

  Aktivity (1)

Článek pro vás napsal Michal Žůrek (misaz)
Avatar
Autor se věnuje tvorbě aplikací pro počítače, mobilní telefony, mikroprocesory a tvorbě webových stránek a webových aplikací. Nejraději programuje ve Visual Basicu a TypeScript. Ovládá HTML, CSS, JavaScript, TypeScript, C# a Visual Basic.

Jak se ti líbí článek?
Celkem (6 hlasů) :
4444 4


 


Miniatura
Předchozí článek
Jednoduchá C# kalkulačka v okně
Miniatura
Všechny články v sekci
Okenní aplikace v C#

 

 

Komentáře
Zobrazit starší komentáře (6)

Avatar
Michal Žůrek (misaz):

přesně tak proto má článek podkapitoly
Implementace prvky

  • z toolboxu
  • z kódu

první varianta je deklarována kdesi v hlubinách kam se většina z nás nikdy nedostane (ve WPF už vůbec ne). A druhá tam taky asi někde je, protože mi to fungovalo.

Nicméně ukončíme debaty. Asi jste stejně všichni pochopili že to mělo jen demonstrovat základy.

Odpovědět 4.9.2013 21:51
Nesnáším {}, proto se jim vyhýbám.
Avatar
Jirka
Člen
Avatar
Jirka:

Jo aha, já jsem postup s Toolboxem ignoroval, protože se mi ze záhadných důvodů komponenta vůbec neobjevila, tak jsem rovnou přešel na postup pomocí kódu.
Vůbec jsem si nevšiml toho druhého progress baru. Tak hlavně, že jsme se domluvili :)

 
Odpovědět 4.9.2013 21:53
Avatar
Jan Vargovský
Redaktor
Avatar
Odpovídá na Jirka
Jan Vargovský:

Když vytvoříš komponentu, musíš potom kód zkompilovat (Debug -> build nebo F6) aby se ti objevil v designeru.

 
Odpovědět 4.9.2013 21:56
Avatar
Zdeněk Pavlátka
Tým ITnetwork
Avatar
Zdeněk Pavlátka:

V článku je několik chyb:

1. prvek na začátku pojmenuješ MujProgressBar.cs a po chvíli tam máš

V Solution Exploreru klikněte na MujOvladaciPrvek.cs, a potom klikněte na Show Code.

2. V kódu metody Increment() máš trochu nesmysl:

public void Increment()
{
        if (this.Value + 1 > maxValue)
                throw new ArgumentOutOfRangeException("Hodnota překročila maximum");
        this.Value += Value; // tím hodnotu zdvojnásobíš, máš přičíst jedničku
}
Odpovědět 10.10.2014 15:11
Kolik jazyků umíš, tolikrát jsi programátor.
Avatar
Jan Vargovský
Redaktor
Avatar
Odpovídá na Zdeněk Pavlátka
Jan Vargovský:

Mezi námi, ta metoda Increment bez parametru (ofc i Decrement) je úplně zbytečná.

viz

public void Increment(int Value)
{
        if (this.Value + Value > maxValue)
                throw new ArgumentOutOfRangeException("Hodnota překročila maximum");
        this.Value += Value;

}

public void Increment()
{
        Increment(1);
}
Editováno 10.10.2014 17:27
 
Odpovědět  +1 10.10.2014 17:26
Avatar
Marek Leopold:

Ahojte,
Tvořím aplikaci, ve které jsem využil vytvoření prvku.
Vložil jsem ho do aplikace, dal mu jméno (prvek.Name = "jmeno"), ale když zkusím jmeno.Hide() tak mi to nefunguje, jak bych měl tedy skrýt mnou vytvořený prvek, který vkládám v kódu, nikoli v designeru ?
Díky

 
Odpovědět 6.3.2015 3:01
Avatar
Odpovědět 6.3.2015 6:11
Nesnáším {}, proto se jim vyhýbám.
Avatar
Marek Leopold:

Děkuji za radu, ale bohužel nefunguje.
Prvek tvořím takto:

Klavesnice kl = null;

private void .... {
Klavesnice kl = new Klavesnice(this);
            kl.Location = new Point((System.Windows.Forms.Screen.PrimaryScreen.Bounds.Width - 624), (System.Windows.Forms.Screen.PrimaryScreen.Bounds.Height - 604));
            Controls.Add(kl);
            kl.Name = "Klavesnic";
            kl.BringToFront(); }

624x602 je velikost, jenom pro upřesnění

... respektive funguje, ale když to zkusím zavolat z jiné části programu, tak mi vždy spadne program

Editováno 6.3.2015 7:29
 
Odpovědět 6.3.2015 7:26
Avatar
Marek Leopold:

Já bych teoreticky mohl vložit tento prvek i přes designer, ale neobjevil se mi v toolboxu.
Měl by to být ten "Klávesnice"

 
Odpovědět 6.3.2015 7:37
Avatar
Odpovídá na Marek Leopold
Michal Žůrek (misaz):

Restartuj Visuak Studio, pak se tam určitě objeví.

Odpovědět 6.3.2015 7:46
Nesnáším {}, proto se jim vyhýbám.
Děláme co je v našich silách, aby byly zdejší diskuze co nejkvalitnější. Proto do nich také mohou přispívat pouze registrovaní členové. Pro zapojení do diskuze se přihlas. Pokud ještě nemáš účet, zaregistruj se, je to zdarma.

Zobrazeno 10 zpráv z 16. Zobrazit vše