2009
11.30

W ASP.NET 2.0 wprowadzono interesującą i wydajną funkcjonalność – Web Parts. Czym są Web Parts? W skrócie: są to pewne zamknięte komponenty aplikacji internetowej, które są tworzone i zarządzane w jednolity sposób. Jedną z najbardziej użytecznych cech web partów (czasami będę odmieniać przez przypadki, ponieważ nie udało mi się znaleźć żadnego dobrego polskiego odpowiednika) jest to, że mogą być one dodawane, usuwane i edytowane nie tylko przez programistów, ale też przez użytkowników Twojej aplikacji internetowej. Web parts w akcji możesz zobaczyć np. na stronie: igoogle.com.

Ten wpis nie będzie o tworzeniu web partów – chcę skupić się na pewnym małym wycinku tematu – mianowicie na tworzeniu połączeń między web partami.

Po co łączyć web parts

Przypuśćmy, że tworzysz aplikację webową, która wyświetla szczegóły na temat europejskich miast. Chciałbyś zorganizować te stroną w taki sposób, żeby korzystała z web parts. W ten sposób umożliwiłbyś użytkownikowi samodzielne zarządzanie wyglądem strony. Załóżmy, że w jednym web parcie użytkownik będzie wpisywał (bądź wybierał z listy) nazwę miasta. W innych web partach pojawią się wówczas informacje takie jak:

  • liczba ludności miasta,
  • slideshow ze zdjęciami z miasta,
  • aktualna prognoza pogody, itd.

Aby uzyskać opisaną funkcjonalność, jako programista, musisz ustalić połączenie między web partami. Można to zrobić na dwa sposoby – 1) ustalić statyczne połączenie lub 2) umożliwić użytkownikom tworzenie dynamicznych powiązań. Omówię pierwszy z nich.

Statyczne powiązanie web partów

Statyczne powiązanie polega na wskazaniu jednego web parta jako dostawcy (provider) i jednego bądź więcej odbiorców (consumer).

Uwaga: dla ułatwienia jako web partów będziemy używać własnych kontrolek (user controls).

Stworzenie dostawcy polega na dodaniu do gotowej kontrolki metody, która będzie zwracała pewną wartość. W naszym przykładzie chcemy, aby była to nazwa miasta pochodząca z rozwijalnej listy. Oto, jak mógłby wyglądać przykładowy kod takiej kontrolki:

public partial class CityChooser : System.Web.UI.UserControl
{

    string _cityName = CityData.GetData().First().Name;

    [ConnectionProvider("My web parts connection", "GetCityName")]
    public string GetCityName()
    {
        return _cityName;
    }

    protected void Page_Load(object sender, EventArgs e)
    {
        if (IsPostBack)
        {
            string userCity = DropDownList1.SelectedValue;
            _cityName = CityData.GetData().First(city => city.Name == userCity).Name;
        }

    }
}

Obiekt CityData zawiera po prostu listę miast w postaci struktur zawierających wszystkie potrzebne dane (np. pole Name czy Population). Dokładny wygląd tej klasy nie jest w tej chwili istotny. Najistotniejsza jest metoda:

[ConnectionProvider("My web parts connection")]
public string GetCityName()
{
    return _cityName;
}

Metoda ta (ważne – publiczna!) zwraca po prostu nazwę miasta wybranego z listy rozwijalnej. Atrybut ConnectionProvider określa, że jest to nasz dostawca danych dla innych web partów (konsumentów). Tu używamy z jednym parametrem (”przyjazną” nazwą połączenia), ale jest też przeciążona wersja z dwoma typu string. Wówczas pierwszy określa “przyjazną” nazwę naszego połączenia, a drugi definiuje unikalną nazwę naszego punktu połączenia. Można pominąć drugi parametr – wówczas nasz punkt będzie się nazywał default (oczywiście, gdybyśmy chcieli zdefiniować drugi ConnectionProvider, to wówczas trzeba już użyć drugiego parametru – nazwa default byłaby już zajęta).

Mamy zatem zdefiniowanego dostawcę naszych danych. Czas na konsumentów.

Stworzenie konsumenta polega na dodaniu do kontrolki będącej web partem metody (znów publicznej), która będzie przyjmować parametr – tego samego typu, jaki jest zwracany przez naszą metodę-dostawcę. Metodą tą należy opatrzyć atrybutem ConnectionConsumer. Całość mogłaby wyglądać następująco:

public partial class PopulationDisplayer : System.Web.UI.UserControl
{
    [ConnectionConsumer("My consumer")]
    public void ShowPopulation(string city)
    {
        lblCityPop.Text = CityData.GetData().First(c => c.Name == city).Population.ToString();
    }
}

I znów najważniejszy jest atrybut ConnectionConsumer. Parametry mają takie samo znaczenie jak w poprzednim przypadku.

Teraz, gdy mamy już zdefiniowanego dostawcę i co najmniej jednego odbiorcę, możemy ustalić połączenie. W tym celu musimy stworzyć stronę, na której będą działać nasze web party. Dodajemy oczywiście kontrolkę WebPartManager oraz WebPartZone, w której w ZoneTemplate umieszczamy nasze web party. Kod kontrolki WebPartZone może wyglądać następująco:

<asp:WebPartZone ID="WebPartZone3" runat="server" Style="width: 650px; height: auto;">
    <ZoneTemplate>
        <uc2:CityChooser ID="Provider" runat="server" />
        <uc3:PopulationDisplayer ID="Consumer" runat="server" />
    </ZoneTemplate>
</asp:WebPartZone>

Samo powiązanie definiujemy natomiast w kontrolce WebPartManager w części StaticConnections:

<asp:WebPartManager ID="WebPartManager1" runat="server">
    <StaticConnections>
        <asp:WebPartConnection
            ID="CityToPopulation"
            ProviderID="Provider"
            ConsumerID="Consumer">
        </asp:WebPartConnection>
    </StaticConnections>
</asp:WebPartManager>

I tak oto, gdy w jednym web parcie z listy wybierzemy miasto, to w drugim zobaczymy liczbę ludności tego miasta:

Powiązanie Web Parts

Powiązanie Web Parts

Gdybyśmy w atrybutach definiujących naszego dostawcę i konsumenta podali unikalne nazwy dla naszych punktów, np:

[ConnectionProvider("My web parts connection", "ProvideData")]
[ConnectionConsumer("My consumer", "ConsumeData")]

wówczas kod kontrolki WebPartManager wyglądałby nieco inaczej:

    <asp:WebPartManager ID="WebPartManager1" runat="server">
        <StaticConnections>
            <asp:WebPartConnection
            ID="CityToPopulation"
            ProviderID="Provider"
            ProviderConnectionPointID="ProvideData"
            ConsumerID="Consumer"
            ConsumerConnectionPointID="ConsumeData">
            </asp:WebPartConnection>
        </StaticConnections>
    </asp:WebPartManager>

Musielibyśmy wówczas określić, że chodzi nam o konkretne metody za pomocą właściwości: ProviderConnectionPointID i ConsumerConnectionPointID.

Gdybyśmy chcieli użyć większej ilości konsumentów, musielibyśmy zdefiniować odpowiednie WebPartConnection dla każdej pary web partów.

W taki sposób można łatwo definiować statyczne połączenia. O tym, jak umożliwić użytkownikom strony tworzenie dynamicznych połączeń, będzie następny (krótki) wpis.

Tym razem załączam kod źródłowy przykładowego rozwiązania – wersja dla Visual Studio 2008. Żeby korzystać z web partów, trzeba mieć SQL Server wersję Express, ponieważ web parts korzystają z bazy danych (App_Data/ASPNETDB.MDF), żeby zapamiętywać preferencje użytkownika. Paczka z kodem nie zawiera tego pliku – trzeba go sobie stworzyć samemu (np. przy pomocy narzędzia ASP.NET Configuration).

vssolutionWebParts static connections – kod C# (6,29 KB)

Do tej pory 1 komentarz

Dodaj własny komentarz
  1. .NET/C# development blog » Łączenie kontrolek Web Parts w ASP.NET 2.0…

    Dziękujemy za publikację – Trackback z dotnetomaniak.pl…