sobota, 20 marca 2010

Tworzenie kontrolek w ASP.NET

ASP.NET pozwala na tworzenie kontrolek, które pozwalają na re użycie kodu pojawiającego się w wielu miejscach tworzonego projektu, czy nawet wielu projektów.

Najprostszym typem kontrolek są kontrolki bazujące na istniejących już kontrolkach. Najłatwiej to opisać jako wrzucanie na formatkę różnych komponentów (labeli, textboxów, buttonów itp.), które następnie w projekcie można przeciągnąć jako pojedynczą kontrolkę. Padnie pytanie: co nam to daje, jeżeli i tak przeciągamy komponenty z toolboxa na formatkę? Daje nam to, że jeżeli w wielu częściach witryny mamy ten sam formularz (np. do wprowadzania adresu lub jakichś spersonalizowanych informacji) nie musimy za każdym razem przeciągać 50 textboxów i buttonów. Dodatkowo możemy w naszej kontrolce zaimplementować potrzebną walidację.

Dla przykładu stworzymy kontrolkę oferującą wprowadzenie adresu.
W VS 2010 (2008 wygląda to tak samo), wybieramy prawym klawiszem nasz projekt i z menu kontekstowego wybieramy Add->Add New Item... Następnie Web User Control, nadajemy jej jakąś nazwę i klikamy na Ok. Do projektu zostanie dodany plik ascx, który następnie pozwala na "przeciągnięcie się do naszej właściwej strony. Niestety, ten rodzaj kontrolki nie pozwala na umieszczenie się w toolbox-ie. A korzystanie ogranicza się do aktualnego projektu.

Kod, który pozwala uzyskać taki wygląd:

<%@ Control Language="C#" AutoEventWireup="true" CodeBehind="Kontrolka.ascx.cs" Inherits="WebApplication1.Kontrolka" %>
<table>
    <tbody>
        <tr>
            <td>Miasto: </td>
            <td><asp:TextBox ID="tbCity" runat="server"></asp:TextBox></td>
        </tr>
        <tr>
            <td>Ulica: </td>
            <td><asp:TextBox ID="tbStreet" runat="server"></asp:TextBox> </td>
        </tr>
        <tr>
            <td>Nr domu: </td>
            <td><asp:TextBox ID="tbStreetNumber" runat="server"></asp:TextBox></td>
        </tr>
        <tr>
            <td>Kod pocztowy: </td>
            <td><asp:TextBox ID="tbPostalCode1" runat="server" MaxLength="2" Width="32px"></asp:TextBox><asp:TextBox
                    ID="tbPostalCode2" runat="server" MaxLength="3" Width="50px"></asp:TextBox></td>
        </tr>
        <tr>
            <td><asp:Button ID="bOk" runat="server" Text="Ok" /></td>
        </tr>
    </tbody>
</table>

Przejdźmy dalej, w naszej aplikacji chcemy aby po kliknięciu w przycisk dodawać np. do listy czy też bazy danych nowe informacje (albo wyszukiwać bazie, w każdym razie zastosować można znaleźć tysiące :)). Osiągnąć możemy to poprzez dodanie zdarzenia, wywoływanego w momencie naciśnięcia przycisku Ok. Zdarzenie tworzy się tak samo jak dla aplikacji WinForms:
1. Tworzymy klasę dziedziczącą po EventArgs:

    public class AdressEventArgs : EventArgs
    {
        public string City { get; private set; }
        public string Street { get; private set; }
        public int StreetNumber { get; private set; }
        public string PostalCode { get; private set; }

        public AdressEventArgs(string city, string street, int streetNumber, string postalCode)
        {
            this.City = city;
            this.PostalCode = postalCode;
            this.Street = street;
            this.StreetNumber = streetNumber;
        }
    }

2. Tworzymy delegatę:

        public delegate void OkButtonClickHandler(object sender, AdressEventArgs e);

3. Tworzymy Event, którego typem jest nasza delegata:

        public event OkButtonClickHandler OkButtonClick;

4. W metodzie kliknięcia przycisku obsługujemy nasz event:

        protected void bOk_Click(object sender, EventArgs e)
        {
            if (OkButtonClick != null)
            {
                OkButtonClick(this, new AdressEventArgs(tbCity.Text, tbStreet.Text, int.Parse(tbStreetNumber.Text), this.tbPostalCode1.Text + "-" + this.tbPostalCode2.Text));
            }
        }

Oczywiście pominąłem tu sprawę walidacji pól.
 Teraz zajmiemy się dodaniem tak stworzonej kontrolki do naszego projektu. Wchodzimy na tworzoną przez nas stronę i przeciągamy z Solution Explorer naszą kontrolkę. Aby obsłużyć nasze zdarzenie dodajemy do metody Page_Init następujący kod:

        protected void Page_Init(object sender, EventArgs e)
        {
            Kontrolka1.OkButtonClick += new Kontrolka.OkButtonClickHandler(Kontrolka1_OkButtonClick);
        }

Oraz w metodzie która służy jako parametr zdarzenia:

        void Kontrolka1_OkButtonClick(object sender, AdressEventArgs e)
        {
            Response.Write(string.Format("{0} {1} {2} {3}", e.City, e.PostalCode, e.Street, e.StreetNumber));
        }

W moim przypadku drukuję na stronie dane które wpisał użytkownik do naszej kontrolki, ale równie dobrze można otrzymane dane wprowadzić do bazy czy też użyć jako parametry do wyszukiwania na mapie itp.

Kilka dodatkowych operacji które mogą nam się przydać podczas pisania własnych kontrolek:
1. Dodawanie dodatkowych właściwości (dostępnych poprzez IntelliSense) pozwalających na np. ustawienie długości textboxa.
Jest to bardzo proste do uzyskania. W klasie kontrolki po prostu dodajemy kolejne właściwości z odpowiednimi atrybutami:



        private int _maxCityLength;

        public int MaxCityLength
        {
            get
            {
                return _maxCityLength;
            }
            set
            {
                _maxCityLength = value;
                tbCity.MaxLength = 5;
            }
        }

2. Dostęp do kontrolek zawartych w User Control.
Ponieważ dodawane kontrolki (np textboxy) w User Control mają atrybut private, nie mamy do nich dostępu z zewnątrz. Najprostszym rozwiązaniem byłoby uczynienie tych elementów publicznymi. Jednak należy tego unikać, gdyż narusza to zasady enkapsulacji. Lepiej wyodrębnić potrzebne nam elementy do właściwości. Jeżeli chcemy np. mieć dostęp do tekstu zawartego w polu city możemy to zrobić np. tak:

        public string CityText
        {
            get
            {
                return tbCity.Text;
            }
            set
            {
                tbCity.Text = value;
            }
        }

Brak komentarzy:

Prześlij komentarz