Části či bloky stránek se velmi často opakují. Proč je tedy neustále dokola opisovat, nebo si dopomáhat různými těžkopádnými způsoby (#include), když .NET framework nabízí jednoduchou znovupoužitelnost často používaného kódu, a to s pomocí uživatelských ovládacích prvků (User Controls). Jejich použití vám ukáži na příkladě počítadla přístupů.

Uživatelské ovládací prvky jsou vlastně samostatnými kusy stránek, které lze do jiných stránek jednoduše vkládat a řešit tím výše popsaný problém. Prvky se nacházejí ve zvláštních souborech s příponou .ascx a od normálních stránek se liší pouze tím, že neobsahují tagy <html>, <body> a <form>.

Připravil jsem jednoduchý příklad uživatelského prvku, který uvidíte na většině webů. Je to počítadlo přístupů, anglicky counter. Pro vylepšení jsem se rozhodl toto počítadlo udělat grafické a automaticky generované, takže již budu využívat zdokonalené funkce systému GDI+, pro kreslení a ukládání obrázku.

Postup bude stejný jako u vytváření klasického webového formuláře, jenom přípona souboru bude jiná. Vytvoříme si tedy soubor jménem HitCounter.ascx. Jeho obsahem bude následující kód:

<%@ Control Language=“c#“ AutoEventWireup=“false“ Codebehind=“HitCounter.ascx.cs“ Inherits=“MyControls.HitCounter“ TargetSchema=“http://schemas.microsoft.com/intellisense/ie5″%>
<asp:Image id=“Counter“ runat=“server“></asp:Image>

Z tohoto kódu lze vyčíst, že se jedná o uživatelský prvek v jazyce C# s vloženým jedním ovládádacím prvkem – Image. Tento prvek se posílá uživateli jako tag <img…

Nyní vytvoříme soubor, který bude obsahovat vlastní logiku tohoto počítadla. Je to soubor HitCounter.ascx.cs s tímto obsahem, který po částech proberu.

namespace MyControls
{
   using System;
   using System.Data;
   using System.Drawing;
   using System.Web;
   using System.Web.UI;
   using System.Web.UI.WebControls;
   using System.Web.UI.HtmlControls;
   using System.IO;
   using System.Drawing.Imaging;
   using System.Drawing.Drawing2D;

Nadeklaroval jsem si jmenný prostor (namespace) jménem MyControls a do něj jsem vložil všechny potřebné odkazy na jmenné prostory, které bude počítadlo využívat. Jsou zde jak jmenné prostory pro přístup k disku a souborům (IO), tak pro kreslení 2D grafiky (Drawing2D) a používání grafických formátů (Imaging).

public abstract class HitCounter : System.Web.UI.UserControl
{
    private Color backcolor = Color.White;
    private int width = 70;
    private int height = 20;
    protected System.Web.UI.WebControls.Image Counter;
    private Font font = new Font(„Arial“, 12, FontStyle.Italic); 

    override protected void OnInit(EventArgs e)
    {
        this.Load += new System.EventHandler(this.Page_Load);
        base.OnInit(e);
    }

    private void Page_Load(object sender, System.EventArgs e) 
    {
        int iHits = 0;

        StreamReader reader = new StreamReader(Server.MapPath(„counter.txt“));
        iHits = Convert.ToInt32(reader.ReadLine());
        reader.Close();

        iHits++;

        StreamWriter writer = new StreamWriter(Server.MapPath(„counter.txt“));
        writer.Write(iHits);
        writer.Close();

Vytvořil jsem třídu HitCounter odvozenou od třídy UserControl a nadeklaroval jsem soukroumé proměnné určující vzhled počítadla. Soukromé jsou proto, protože přístup k nim je uskutečněn pomocí vlastností a tím je dodržena jedna ze zásad objektově orientovaného programování – zapouzdřenost.

Ještě je tu jedna proměnná s názvem Counter, která je odvozena od třídy Image a poskytuje přístup do ovládacího prvku Image, nadeklarovaného v souboru HitCounter.ascx. Funkce OnInit nastavuje, že funkce Page_Load je událostí na událost Load. Následuje volání funkce OnInit základní třídy (UserControl). Hlavní logika je umístěna ve funkci Page_Load. Funkce si otevře proud dat na čtení ze souboru counter.txt, z toho přečte řetězec a převede ho do číselného formátu. Pak tento proud zavře. Následuje zvetšení počtu přístupů o jedna a jeho zapsání podobným způsobem zpět do souboru.

        Bitmap picture = new Bitmap(width, height, PixelFormat.Format24bppRgb);
        Graphics g = Graphics.FromImage(picture);

        g.SmoothingMode = SmoothingMode.AntiAlias;
        g.Clear(backcolor);
        g.DrawRectangle(Pens.White, 1, 1, width-3, height-3);
        g.DrawRectangle(Pens.Gray, 2, 2, width-3, height-3);
        g.DrawRectangle(Pens.Black, 0, 0, width, height);

        StringFormat format = new StringFormat();
        format.Alignment = StringAlignment.Center;

        g.DrawString(iHits.ToString(), font, SystemBrushes.WindowText, new
        RectangleF(0, 0, width, height), format);

        picture.Save(Server.MapPath(„counter.jpg“), ImageFormat.Jpeg);
        g.Dispose();
        picture.Dispose();
        Counter.ImageUrl = „counter.jpg“;
        Counter.AlternateText = „Counter“;
}

Tato část kódu zajišťuje právě ono vykreslování počítadla. Vytvoří se nová bitmapa a z ní se vezme třída Graphics, pomocí které se kreslení provádí. Následuje nastavení vyhlazovacího módu a vyplnění pozadí barvou. Dále se vykreslí obdélníky, které dělají rám počítadla. S pomocí třídy StringFormat se nastaví zarovnání textu na střed. Funkce DrawString nakreslí doprostřed číslo získané ze souboru. Celý tento obrázek se uloží funkcí Save do souboru counter.jpg. Uvolní se zdroje používané třídou Graphics a Bitmap. Ovládacímu prvku Counter(Image) se nastaví cesta na obrázek counter.jpg a AlternateText pro případ nezobrazení počítadla.

        public Color BackColor
        {
                get {return backcolor;}
                set {backcolor = value;}
        }
        public int Width
        {
                get {return width;}
                set {width = value;}
        }
        public int Height
        {
                get {return height;}
                set {height = value;}
        }
        public Font TextFont
        {
                get {return font;}
                set {font = value;}
        }
    }
  }

Toto jsou již zmiňované vlastnosti tohoto počítadla. Jejich změna z venku je promítnuta do chování, či vzhledu počítadla.

Počítadlo je nyní hotové. Je však nutné si k němu dodělat ještě testovací stránku. Ta se bude jmenovat Test.aspx  a bude obsahovat tento kód:

<%@ Page language=“c#“ Codebehind=“Test.aspx.cs“ AutoEventWireup=“false“ Inherits=“HitCounter.Test“ %>
<%@ Register TagPrefix=“uc“ TagName=“HitCounter“ Src=“HitCounter.ascx“ %>
<!DOCTYPE HTML PUBLIC „-//W3C//DTD HTML 4.0 Transitional//EN“ >
<HTML>
     <HEAD>
         <title>Testování počítadla</title>
     </HEAD>
     <body>
         Počet přístupů: <uc:hitcounter id=“HitCounter1″ runat=“server“ BackColor=“#00ccff“></uc:hitcounter>
     </body>
</HTML>

Zde bylo nutné přidat direktivu <%@ Register, kterou jsme dali frameworku najevo, že používáme uživatelský ovládací prvek a odkud ho používáme. Pomocí programového kódu této stránky by bylo možné měnit vlastnosti počítadla, ale pro demonstraci tento příklad postačuje.

Ještě je nutné do adresáře, kde celý tento projekt je, tedy wwwroot\… vytvořit soubor counter.txt a zadat do něho počáteční hodnotu (obvykle to bývá nula).

Starší komentáře ke článku

Pokud máte zájem o starší komentáře k tomuto článku, naleznete je zde.

1 Příspěvěk v diskuzi

  1. Dobrý den,
    mám malinký problém a to v souboru HitCounter.ascx a píše mi to chybu
    Could not load type ‚HitCounter‘.
    prosím poradte mi v čem by mohla být chyba děkuji Chudik

Odpovědět