Články

Tisk článku Tisk článku

Vytváření vlastních komponent

[Zpět na kategorii]

Datum: 28. 6. 2007 20:59       Autor: Tomáš Herceg       Zobrazeno: 9289x

Kategorie: Komponenty

Témata: VB.NET

Určitě jste někdy potřebovali víc komponent seskupit do jedné, abyste tuto skupinu mohli používat snadno na více místech. A právě o tom je i tento článek - naučíme se vytvořit si vlastní komponentu a deklarovat jí vlastnosti.


Často se nám stává, že na rozsáhlejším formuláři se nám to hemží mnoha skupinami komponent, které prakticky vzato dělají to samé, akorát s jinými hodnotami. Občas potřebujeme chování takové skupiny změnit, ale to znamená, že musíme tyto změny provést na více místech, podle toho, kolik skupin používáme. Dnes se mě jeden člověk ptal, jestli se nedá víc komponent seskupit k sobě, a tak jsem se rozhodl, že o tom napíšu článek. Není to vůbec složité.

Přidání User Control

User Controls jsou komponenty, které si poskládáme sami z komponent již existujících. Visual Studio nám samozřejmě umožňuje vizuálně navrhnout vzhled celé komponenty, stejně jako navrhujeme i formuláře. Vytvořte si tedy nový projekt Windows Application, v Solution Exploreru klikněte pravým tlačítkem na název projektu a vyberte v nabídce Add položku User Control. Pojmenujte ji třeba FolderPicker.

Naše komponenta bude složena z textového pole, tlačítka a obrázku. Do textového pole buď sami zapíšeme nějakou cestu, nebo klikneme na tlačítko Procházet a cestu vybereme z dialogu. Pokud zadaná cesta existuje, ukáže se obrázek zelené fajfky, jinak bude schovaný. Přidejte tedy na formulář komponenty TextBox, Button a PictureBox. Vhodně je uspořádejte a do PictureBoxu nahrajte obrázek zelené fajfky (nejprve na obrázek klikněte pravým tlačítkem a vyberte Uložit obrázek jako...).

Obrázek fajfky ke stažení

Hotová komponenta by měla vypadat asi takto:

Komponenta

Pokročilá nastavení velikosti komponenty

Protože uživatelé mohou měnit velikost této komponenty, musíme nastavit ještě pár vlastností. Výška komponenty musí zůstat stále stejná. Nebudeme ji zvětšovat ani zmenšovat. Každá komponenta má k tomuto účelu vlastnosti MaximumSize a MinimumSize. Vlastnost MinimumSize nastavte na 200; 40 a vlastnost MaximumSize nastavte na 1000; 40. Tím omezíme minimální a maximální velikost komponenty - první číslo je šířka a druhé výška. Obě tyto vlastnosti jsou datového typu System.Drawing.Size, který má vlastnosti Width a Height. Těm se přiřazují právě tato dvě čísla.

Komponentu tedy můžeme nyní roztahovat jen do šířky. Zde je ale další problém - při změně velikosti se komponenty nechovají tak, jak by měly. Zůstanou na místě a neposunují se spolu s komponentou. Na většinu takových situací nám stačí vlastnost Anchor, což v překladu znamená kotva. Má čtyři nastavení, která můžeme dohromady kombinovat. Pokud ji budete chtít nastavit, ukáže se speciální ovládací prvek, v němž můžete nastavit čtyři směry. Vyberte tedy nejprve obrázek a nastavte mu kotvu na směry vpravo a nahoru. Pokud je nastavená kotva, při změně velikosti bude komponenta od okrajů na zvolených stranách udržovat stejnou vzdálenost. Pokud tedy celou komponentu rozšíříme, obrázek bude udržovat dstále stejnou vzdálenost od pravého kraje komponenty. Bude se tedy posouvat vpravo či vlevo a bude mát od pravého kraje komponenty stále stejnou vzdálenost. To samé nastavení dejte i tlačítku.

Zbývá nám textové pole. Tam zapněte kotvu vlevo, vpravo a nahoře. Protože textové pole musí udržovat stále stejnou vzdálenost od pravého i od levého okraje komponenty, při roztahování mu nezbyde než se roztahovat spolu s komponentou. Pokud tedy teď zkusíte komponentě měnit velikost, bude se chovat správně.

Aplikační logika komponenty

Ještě před psaním kódu nastavte obrázku vlastnost Visible na False, aby ze začátku nebyl vidět. Do kódu přidáme nejprve proceduru CheckPathExists, která zobrazí či schová obrázek podle toho, jestli zadaná cesta existuje. Přepněte se tedy do režimu kódu a vložte sem tyto řádky:

    Public Sub CheckPathExists()
        'zjistit, jestli cesta existuje, a podle toho ukázat nebo schovat fajfku
        PictureBox1.Visible = IO.Directory.Exists(TextBox1.Text)
    End Sub

Tuto kontrolu musíme zajistit, pokud opustíme textové pole. Je zbytečné kontrolovat cestu po každém znaku (pokud by byla cesta v síti, asi by to i dost zpomalovalo), stačí tedy provést kontrolu, jakmile kurzor opustí textové pole a přeskočí na jinou komponentu. V rozbalovacích seznamech nahoře tedy vyberte hodnoty TextBox1 a LostFocus, vytvoří se nám procedura události LostFocus, která nastane, když kurzor opustí textové pole (např. po kliknutí jinam nebo po stisku tabulátoru).

    Private Sub TextBox1_LostFocus(ByVal sender As Object, ByVal e As System.EventArgs) Handles TextBox1.LostFocus
        CheckPathExists()
    End Sub

Nyní ještě zbývá naprogramovat tlačítko Procházet. Přidejte do naší komponenty ještě komponentu FolderBrowserDialog, což je dialog pro výběr cesty. Poklepejte na tlačítko Procházet a zapište do něj tento kód:

    Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
        'vybrat cestu pomocí dialogu
        If FolderBrowserDialog1.ShowDialog = DialogResult.OK Then
            TextBox1.Text = FolderBrowserDialog1.SelectedPath
            CheckPathExists()
        End If
    End Sub

Tato komponenta je odvozena od formuláře, má tedy metodu ShowDialog, která okno zobrazí a počká, dokud jej uživatel neuzavře. Další kód se provádí až potom, když je dialog pryč. Tato metoda vrátí OK, pokud uživatel složku vybral a potvrdil (mohl totiž také kliknout na Storno a to pak nebudeme dělat nic). Pokud tedy složku opravdu vybral, nastavíme její cestu do textového pole a zkontrolujeme, jestli existuje. To by byla ta jednodušší část. Pokud se přepnete na formulář, v soupravě nástrojů se naše komponenta objeví. Můžete si ji na formulář přidat a vyzkoušet.

Vlastnosti komponenty

Pokud jste komponentu zkusili někde použít, jaké asi bylo vaše překvapení, když jste zjistili, že se z formuláře na vnitřní komponenty jen tak nedostanete. Naše vlastní komponenty má totiž jen ty vlastnosti, které má třída System.Windows.Forms.Control, což je jakási obecná komponenta, od které jsou odvozeny všechny ostatní (říká se tomu dědičnost). My bychom určitě potřebovali vlastnosti SelectedPath IsValid. První vlastnost vrátí cestu, která je v komponentě zadaná, a druhá vrátí True, pokud je cesta správná, jinak vrátí False.

Tyto vlastnosti musíme v komponentě nadeklarovat. Používá se k tomu speciální konstrukce Property. Ta má dvě části - Get a Set. Get je vlastně funkce, která vrátí hodnotu této vlastnosti, a Set je procedura, která nastaví předanou hodnotu do této vlastnosti. Názorně je to vidět na příkladu vlastnosti SelectedPath:

    Public Property SelectedPath() As String
        Get
            Return TextBox1.Text
        End Get
        Set(ByVal value As String)
            TextBox1.Text = value
            CheckPathExists()
        End Set
    End Property

Mezi řádky Get a End Get máme vlastní kód funkce Get - je to jediný řádek, který způsobí, že funkce Get vrátí text zapsaný v komponentě TextBox1. Mezi řádky Set(value As String) a End Set musíme hodnotu value předanou jako parametr do komponenty nastavit. Přiřadíme ji tedy jako text do komponenty TextBox1 a ještě zkontrolujeme správnost cesty a podle toho možná ukážeme fajfku.

Tato deklarace samozřejmě patří do souboru s naší komponentou, ne do formuláře. Musí být uvnitř třídy FolderPicker, což je třída naší komponenty. Z jiného místa totiž nemůžeme přistupovat ke komponentě TextBox1.

Tento kód se navenek projeví tak, že ve formuláři v komponentě uvidíme vlastnost SelectedPath stejně, jako všechny ostatní vlastnosti. Můžeme jí přiřazovat hodnoty nebo je z ní číst tak, jak to děláme s jinými vlastnostmi. Uvnitř má však každá vlastnost svoji Get a Set (speciální vlastnosti jen jednu z nich) a ty obsahují opět nějaký kód.

Druhá vlastnost IsValid vrací True nebo False podle toho, jestli je zadaná cesta správná. Do této vlastnosti ale nemůžeme přiřazovat, jedná se tedy o speciální typ vlastnost, která má jen funkci Get. Tato vlastnost je ReadOnly (jen ke čtení) a to také musíme zapsat do její deklarace:

    Public ReadOnly Property IsValid() As Boolean
        Get
            Return PictureBox1.Visible
        End Get
    End Property

Je to velmi jednoduché - vrátíme hodnotu vlastnosti Visible komponenty PictureBox1. Pokud je totiž obrázek fajfky vidět (Visible = True), cesta je správná a musíme vrátit True. Pokud fajfka vidět není, vrátíme False.

A to je prakticky vše - naučili jsme se vytvářet vlastní komponentu a deklarovat jí vlastnosti, které potřebujeme. Nezapomeňte na klíčové slovo ReadOnly před vlastnostmi jen pro čtení. Všechny deklarace vlastností musí obsahovat na začátku klíčové slovo Public, aby byly vidět zvenku. Jinak je můžeme používat opět pouze z nějaké komponenty.


> Na začátek

 

Hodnocení:

Hlasů: 6
Zvolte své hodnocení

Tomáš Herceg

Jsem hlavním softwarovým architektem ve společnosti Riganti. Mám dlouholeté zkušenosti s technologiemi ASP.NET, Silverlight, WPF a XNA. Působím též jako lektor ve společnosti Gopas a již třetím rokem jsem držitelem ocenění Microsoft Most Valuable Professional.

Podpořte vznik dalších článků

Související články

Žádné související články nebyly nalezeny.

RSS Feed RSS Feed

Diskuse

nejak to nechodí

Datum: 1.8.2007 14:56
Autor: neregistrovaný (88.103.121.103)
Hodnocení autora: není
Příspěvků: 0
Podle článku jsem vytvořil komponentu ( ve VB2005 express), ale jak se píše "... Pokud se přepnete na formulář, v soupravě nástrojů se naše komponenta objeví." .... tak se komponeta neobjevila. Celé jsem to přepsal ještě jednou a nic. Nebyla by rada co stím? Díky.
 
           [Odpovědět]
 
Hodnocení: 1 Čekejte, prosím...

Re: nejak to nechodí

Datum: 1.8.2007 15:06
Autor: neregistrovaný (213.210.158.150)
Hodnocení autora: není
Příspěvků: 0
V menu Build klikněte na položku Build <náev projektu>. Pravděpodobně musíte projekt mít uložený.
 
           [Odpovědět]
 
Hodnocení: 0 Čekejte, prosím...

Re: Re: nejak to nechodí

Datum: 5.8.2007 20:26
Autor: neregistrovaný (85.160.190.199)
Hodnocení autora: není
Příspěvků: 0
Díky za radu uz to funguje dle očekávání.
 
           [Odpovědět]
 
Hodnocení: 0 Čekejte, prosím...

Re: Re: Re: nejak to nechodí

Datum: 14.8.2007 22:02
Autor: neregistrovaný (77.237.138.105)
Hodnocení autora: není
Příspěvků: 0
Zdravím,
občas se mi také stává, že se mi komponenta nezobrazí, ale já to řeším tak, že uložím a opět vyvolám projekt, pak je vše OK.
Přeji hezký den
 
           [Odpovědět]
 
Hodnocení: 0 Čekejte, prosím...

Úprava komponenty Calendar

Datum: 13.8.2008 11:25
Autor: Petr S
Hodnocení autora: -1
Příspěvků: 48
Chtěl bych změnit "tooltip" u komponenty Calendar: při nájezdu kurzoru na posun měsíce v kalendáři se nabídne textík v angličtině "Go to the (previous)next month" - je možno to nějak změnit do češtiny?
 
           [Odpovědět]
 
Hodnocení: 0 Čekejte, prosím...

Re: Úprava komponenty Calendar

Datum: 13.8.2008 12:11
Autor: Tomáš Herceg
Hodnocení autora: 1660
Příspěvků: 3533
Projděte všechny vlastnosti této komponenty, určitě se nějakou z nich tento text nastavuje. Určitě to v té komponentě nemají natvrdo.
 
           [Odpovědět]
 
Hodnocení: 2 Čekejte, prosím...

Re: Úprava komponenty Calendar

Datum: 13.8.2008 16:25
Autor: neregistrovaný (217.117.222.236)
Hodnocení autora: není
Příspěvků: 0
Fakticky to změnit nejde. I když názvy měsíců na okrajích komponenty (vlastnost NextPrevFormat) nahradím vlastním - např.slovy Příští a Minulý, stále se tooltip objeví anglicky. Přitom vlastnost Tooltip, kteru je možno měnit, se vztahuje pouze k najetí kurzoru na celou komponentu.
Nejde ale o život...
Díky.
 
           [Odpovědět]
 
Hodnocení: 0 Čekejte, prosím...

Re: Úprava komponenty Calendar

Datum: 8.5.2011 0:57
Autor: neregistrovaný (94.123.201.71)
Hodnocení autora: není
Příspěvků: 0
lingerie, fantazi iç giyim http://www.bayaniccamasir.com ,
elbise modelleri http://www.gozdekadin.com moda, magazin,
gelinlik modelleri, evlilik, http://www.ruyadugun.com
flange,flanges, flanş, http://www.demirtasmakina.com
klima, toshiba, http://www.klimafiyatlar.com
iç giyim, bayan iç giyim, http://www.ucuzicgiyim.net
tanga, http://www.tangasepeti.com
lingerie http://www.kadinicgiyim.net
 
           [Odpovědět]
 
Hodnocení: -3 Čekejte, prosím...
 

VBNET.CZ | © 2007 Tomáš Herceg, Tomáš Jecha | Kopírování a přejímání jakéhokoliv obsahu z tohoto webu je bez písemného svolení autorů zakázáno.