Hova kattintottam?

Gyakori feladat, hogy megjelenítjük az adatokat egy weboldalon és szeretnénk biztosítani a felhasználónak, hogy valamelyik rekordra kattintva ilyen vagy éppen olyan műveletet végezzen el az adott soron. Valami oknál fogva a szokásos fejlesztői hozzáállás a feladathoz az, hogy a gomb kattintás eseménykezelőjében elkezdjük keresgélni, hogy vajon melyik rekordra kattinthatott szerencsétlen felhasználó és ilyenkor az ember hajlamos elveszni a SelectedItem, SelectedIndex, DataItem, DataRow, DataRowView, DataRowItem és társai között.

Ennél sokkal szerencsésebb hozzáállás, ha a gomb eleve tudja magáról, hogy melyik rekordhoz tartozik!

Íme egy példa, még pedig Visual Studio 2008-cal, Northwind adatbázissal és természetesen LINQ-kel. A VS 2008 remek grafikus dizájnerében létrehoztam egy LINQ to SQL adatmodellt NorthwindDataContext néven, majd ehhez konfiguráltam egy LinqDataSource vezérlőt egy ASPX oldalon:

  <asp:LinqDataSource ID="ldsNorthwind" runat="server" 
    ContextTypeName="NorthwindDataContext" TableName="Products">
  </asp:LinqDataSource>

Ezek után felhasználtam az új ListView vezérlőt, hogy megjelenítsem az adatokat az adatforrás segítségével. A célom az volt, hogy az adatok egy felsorolásos listában jelenjenek meg és mindegyik mellett legyen egy Összegez és egy Számol feliratú gomb, amivel az adott termékhez tartozó megrendeléseket tudom megszámolni és összesíteni. Ezekhez a műveletekhez definiáltam két gombot:

  <asp:ListView ID="lvProducts" runat="server" 
DataSourceID="ldsNorthwind" onitemcommand="lvProducts_ItemCommand"> <LayoutTemplate> <ul> <asp:PlaceHolder ID="itemPlaceholder" runat="server" /> </ul> </LayoutTemplate> <ItemTemplate> <li> [<asp:LinkButton id="btnSum" runat="server" Text="Összegez"
CommandName="Sum" CommandArgument='<%# Eval( "ProductID" ) %>' />] [<asp:LinkButton id="btnCount" runat="server" Text="Számol"
CommandName="Count" CommandArgument='<%# Eval( "ProductID" ) %>' />] - <%# Eval( "ProductName" ) %> </li> </ItemTemplate> </asp:ListView>

A gombnyomások kezeléséhez feliratkoztam a ListView ItemCommand eseményére. Hogy egyszerűen le tudjam kérdezni ebben az eseménykezelőben, hogy melyik gombra kattintott a felhasználó, a két gombnak eltérő CommandName értéket állítottam be. Bár szerver oldalon természetesen le lehet kérdezni a gombok feliratát is, azzal a gond, hogy azt lokalizálhatjuk, az ID értéke pedig szerintem nem annyira beszédes a kódban.

A lényeg: a gombok CommandArgument tulajdonságához odakötöttem a rekordot egyedileg azonosító ProductID mező értékét. Mivel a CommandArgument értékét egyszerű lekérdeznem az eseménykezelőben, így nem kell azzal küzdenem, hogy vajon melyik sorra kattintott a felhasználó, sőt a sor száma nem is érdekel, rögtön megkapom a rekord egyedi azonosítóját, ahonnan már csak egy ugrás a teljes rekord megszerzése.

Az ItemCommand eseménykezelő pedig így sikerült:

  protected void lvProducts_ItemCommand( object sender, ListViewCommandEventArgs e )
  {            
    NorthwindDataContext dc = new NorthwindDataContext();
    Product product = dc.Products.First( p => p.ProductID == Convert.ToInt32( e.CommandArgument ) );

    string result = default( string );

    switch( e.CommandName )
    {
      case "Sum":
        result = String.Format( "{0:c}", product.OrderDetails.Sum( o => o.Quantity * o.UnitPrice ) );
        break;
      case "Count":
        result = String.Format( "{0} darab", product.OrderDetails.Count() );
        break;
    }

    this.litResult.Text = result;
  }

Kihasználom, hogy az e.CommandArgument a rekord egyedi azonosítója és LINQ to SQL szintaktikával egyetlen sor kódot igényel a ProductID alapján egy Product példány megszerzése. Kihasználom, hogy az e.CommandName jól megkülönbözteti egymástól a két gombot és ezzel a két elvégzendő műveletet is, ami itt a példában egy összegzés és egy számlálás.

Ennél egyszerűbben talán csak úgy lehetne megoldani a feladatot, ha az egyes ListView rekordokba nem csak az ID-t, hanem a teljes objektum példányt el tudnánk menteni, azonban ezt valószínűleg sávszélesség okokból amúgy sem akarnánk.

A lényeg: ne keresgéljük a cél rekordot, mondja el az, hogy mit akar.

A teljes forráskód letölthető az MSDN Kompetencia Központ honlapjáról.

 

Vélemény, hozzászólás?

Adatok megadása vagy bejelentkezés valamelyik ikonnal:

WordPress.com Logo

Hozzászólhat a WordPress.com felhasználói fiók használatával. Kilépés / Módosítás )

Twitter kép

Hozzászólhat a Twitter felhasználói fiók használatával. Kilépés / Módosítás )

Facebook kép

Hozzászólhat a Facebook felhasználói fiók használatával. Kilépés / Módosítás )

Google+ kép

Hozzászólhat a Google+ felhasználói fiók használatával. Kilépés / Módosítás )

Kapcsolódás: %s