Érték szerinti csoportosítás ListView vezérlővel

Gyakran van szükség arra, hogy a ListView vezérlőben megjelenő rekordokat valamilyen szempont szerint csoportosítsuk. A ListView támogat is csoportosítást, azonban ez a funkció csak arra jó (?), hogy megadott számú elemet tegyünk egy csoportba, azt sajnos nem támogatja, hogy megadott érték szerint csoportosítsuk a rekordokat. Persze hagyományos módon meg lehet oldani ezt is.

Ezt tudja a ListView csoportosítás címén: a LayoutTemplate-et GroupTemplate-ekkel tölti fel, közéjük pedig GroupSeparatorTemplate-et rak. Minden egyes GroupTemplate-be a GroupItemCount tulajdonságban megadott számú ItemTemplate kerül. Ha egy csoportban (tipikusan az utolsóban) nincs elég elem, akkor azokat a helyeket EmptyItemTemplate-tel tölti fel. Ez szerintem arra van kitalálva, hogy az ember táblázatba rendezze a rekordokat, ott számít ugyanis, hogy minden sorba ugyanannyi elem kerüljön.

De mi van akkor, ha nem darabszám, hanem érték szerint akarjuk csoportosítani a sorokat? Ez esetben kénytelenek leszünk lemondani a beépített csoportosításról és az ASP.NET 1.0-ban megszokott módon megoldani a feladatot.

Először is rendezzük a csoportképző mező szerint az adatokat, például ha a Northwind adatbázis Customer táblájának sorait ország szerint csoportosítva, azon belül pedig cégnév szerint rendezve akarjuk megjeleníteni, akkor így:

  SELECT CompanyName, ContactName, Country FROM Customers ORDER BY Country, CompanyName

Az eredmény (részlete):

Northwind Customers ország szerint

Már csak annyi dolgunk maradt, hogy a Country mezőváltozásai esetén kell megjelenítenünk egy csoportfejlécet. A trükk az, hogy nem használjuk a beépített csoportosítást, hanem (például) egy sima h2 elemre rácuppanunk szerver oldalon (runat=server), majd a Visible tulajdonságát egy szerver oldali metódussal állítjuk be:

    <asp:ListView runat="server" DataSourceID="sdsCustomers">
        <LayoutTemplate>
            <asp:PlaceHolder ID="itemPlaceholder" runat="server" />
        </LayoutTemplate>
        
        <ItemTemplate>
            <h2 runat="server" visible='<%# IsGroupHeaderVisible( Eval( "Country" ) ) %>'>
                <%# Eval( "Country" ) %>
            </h2>
        
            <%# Eval( "CompanyName" ) %>
            -
            <%# Eval( "ContactName" ) %>
        </ItemTemplate>
        
        <ItemSeparatorTemplate>
            <br />
        </ItemSeparatorTemplate>            
    </asp:ListView>

Ezek után a code behindban kell egy privát mező az előző érték tárolására és a függvény, ami az aktuális értéket összehasonlítja az előzővel:

  private string _lastValue;

  protected bool IsGroupHeaderVisible( object value )
  {
    string currentValue = value.ToString();

    if( currentValue.Equals( this._lastValue, StringComparison.OrdinalIgnoreCase ) )
    {
        return false;
    }
    else
    {
        this._lastValue = currentValue;
        return true;
    }
  }

Az eredmény pedig:

Northwind Customers ország szerint ListView-val

Látható, hogy az egész azon alapul, hogy a rekordok jó sorrendben legyenek, de egyébként teljesen a mi kezünkben van az irányítás, olyan szempont szerint csoportosítunk, ahogy kedvünk tartja.

A cikkhez tartozó forráskód letölthető itt.

Technorati-címkék: ,,

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