Ext.NET GridPanel HOW-TO

Στο σημερινό Sunday’s Dev Digest παρουσιάζω ένα απλό παράδειγμα χρήσης του Ext.NET GridPanel.

Τι θα χρειαστούμε:

  • Ένα ASP.NET Empty Web Application (Visual Studio –> File –> New –> Project –> ASP.NET Empty Web Application)
  • Μια ASPX σελίδα (Δεξί κλίκ στο project –> Add –> New Item –> Web Form)
  • Εγκατάσταση του Ext.NET στο project. Ο πιο εύκολος τρόπος είναι να κάνουμε χρήση του NuGet package και στο Package Manager Console (View –> Other Windows –> Package Manager Console) γράφουμε:
install-package ext.net

Για την χρήση των Ext.NET components στην ASPX σελίδα μας χρειαζόμαστε οπωσδήποτε την δήλωση του Ext.Net Assembly:

<%@ Register Assembly="Ext.Net" Namespace="Ext.Net" TagPrefix="ext" %>

και χρήση του Ext.Net ResourceManager component στην αρχή της σελίδας (θεωρείτε, αν θέλετε, τον ResourceManager κάτι σαν τον ScriptManager του ASP.NET AJAX):

<ext:ResourceManager runat="server" />

Το Ext.NET GridPanel

Για να χρησιμοποιήσουμε το GridPanel εισάγουμε το παρακάτω markup:

<ext:GridPanel ID="GridPanel1" runat="server" Title="Σκευάσματα" Border="false" StripeRows="true" TrackMouseOver="true"
                AutoExpandColumn="Skeyasma" Icon="Table" StoreID="Store1">              
    <ColumnModel>
        <Columns>
            <ext:RowNumbererColumn />
            <ext:Column ColumnID="Id" Header="Id" DataIndex="id" />
            <ext:Column ColumnID="Skeyasma" Header="Product" DataIndex="skeyasma">
                <Editor>
                    <ext:TextField ID="TextField1" runat="server" />
                </Editor>
            </ext:Column>
            <ext:Column ColumnID="Timh" Header="Price" DataIndex="timh" Align="Right">
                <Renderer Format="EuroMoney" />
                <Editor>
                    <ext:TextField ID="TextField2" runat="server" />
                </Editor>
            </ext:Column>
        </Columns>
    </ColumnModel>
    <View>
        <ext:GridView ForceFit="true" />
    </View>
    <SelectionModel>
        <ext:RowSelectionModel ID="RowSelectionModel1" runat="server">
        </ext:RowSelectionModel>
    </SelectionModel>
    <SaveMask ShowMask="true" />
    <LoadMask ShowMask="true" />
</ext:GridPanel>  

Το GridPanel χρειάζεται ένα μοντέλο στηλών (ColumnModel) το οποίο καθορίζει τις στήλες που θα εμφανίζονται. Η κάθε στήλη συνδέεται με ένα data field μέσω του DataIndex property. Επίσης, μπορούμε να ορίσουμε πιο component επιθυμούμε ως editor για κάθε στήλη όταν τo grid βρίσκεται σε κατάσταση edit. Στο παραπάνω παράδειγμα, όταν διορθώνουμε ή προσθέτουμε μια εγγραφή, η καταχώρηση για τις στήλες Skeyasma και Timh θα γίνεται μέσω ενός απλού textbox. Αντίθετε η στήλη Id δεν ορίζει Editor και έτσι παραμένει μόνο-για-ανάγνωση (πρόκειται άλλωστε για το auto increment key field του πίνακα). Πρόκειται λοιπόν για ένα grid το οποίο μας παρέχει όλες τις δυνατότητες CRUD (μπορούμε να εισάγουμε, να διορθώσουμε και να διαγράψουμε δεδομένα).

To View περιλαμβάνει επιλογές για τον τρόπο προβολής των δεδομένων στο grid ενώ το SelectionModel απλά καθορίζει πως θα γίνεται η επιλογή των δεδομένων (στο παράδειγμά μας, επιτρέπεται η επιλογή ολόκληρης της γραμμής (data row) όπου και αν κάνει κλικ ο χρήστης).

Τέλος, ορίζουμε ότι επιθυμούμε να εμφανίζεται μήνυμα αναμονής όταν διαβάζουμε ή αποθηκεύουμε δεδομένα. Όλες οι λειτουργίες υλοποιούνται μέσω AJAX και όταν είναι χρονοβόρες το grid εμφανίζεται ως εξής:

image

Το DataStore

Πως όμως επικοινωνεί το grid με την πηγή των δεδομένων; Ανέφερα παραπάνω ότι οι στήλες συνδέονται με data fields. Που όμως ορίζονται αυτά; Η απάντηση βρίσκεται στο Ext.Net Store component. Είναι μια από τις δυο έννοιες που πρέπει να συνηθίσει κανείς όταν δουλεύει με το Ext.NET (η δεύτερη είναι τα Events).

Το Ext.Net Store καθορίζει ακριβώς ποιά είναι η πηγή των δεδομένων και ποιά data fields θέλουμε να χρησιμοποιήσουμε. Καθορίζει επίσης την μορφή με την οποία θέλουμε να τα “καταναλώσουμε” (JSON, XML ή Array Reader), τις ιδιότητες των πεδίων (π.χ. ποιό είναι το key field), το sortάρισμα που πιθανόν θέλουμε κ.ο.κ. Τέλος, έχουμε την δυνατότητα να ορίσουμε μια σειρά από event handlers για διάφορα γεγονότα όπως π.χ. OnRefreshData, OnSubmitData, ΟnException κ.ο.κ. Είναι σημαντικό να αναφέρουμε ότι οι event handlers μπορεί να είναι τόσο server όσο και client side (C# methods ή Javascript functions αντίστοιχα).  Περισσότερα για τo Ext.Net Event Model σε επόμενο post.

Το Ext.Net Store είναι πανίσχυρο. Μπορεί να συνδεθεί με διάφορα data sources, για παράδειγμα με έναν SQL Server ή αρχεία XML. Στο σημερινό παράδειγμα θα συνδεθούμε με τον SQL Server μέσω ενός κλασσικού, απλού SqlDataSource component:

Σημείωση: το ConnectionString και η πηγή δεδομένων του παραδείγματος αναφέρονται σε μια δική μου SQL Server βάση, με έναν πίνακα τριών πεδίων (id,skeyasma,timh). Φυσικά, πρέπει να ορίσετε το δικό σας ConnectionString και να συνδεθείτε σε μια δική σας βάση αλλάζοντας τα ονόματα των πεδίων κλπ.

<asp:SqlDataSource ID="SqlDataSource1" runat="server" 
    ConnectionString="<%$ ConnectionStrings:pharmakadbConnectionString %>" 
    DeleteCommand="DELETE FROM [pharmaka_skeyasmata] WHERE [id] = @id" 
    InsertCommand="INSERT INTO [pharmaka_skeyasmata] ([timh], [skeyasma]) VALUES (@timh, @skeyasma); SELECT @newId = @@Identity;" 
    SelectCommand="SELECT [id], [timh], [skeyasma] FROM [pharmaka_skeyasmata] WHERE [human]=0" 
    UpdateCommand="UPDATE [pharmaka_skeyasmata] SET [timh] = @timh, [skeyasma] = @skeyasma WHERE [id] = @id">
    <DeleteParameters>
        <asp:Parameter Name="id" Type="Int32" />
    </DeleteParameters>
    <InsertParameters>
        <asp:Parameter Name="timh" Type="String" />
        <asp:Parameter Name="skeyasma" Type="String" />
        <asp:Parameter Direction="Output" Name="newId" Type="Int32" />
    </InsertParameters>
    <UpdateParameters>
        <asp:Parameter Name="timh" Type="String" />
        <asp:Parameter Name="skeyasma" Type="String" />
        <asp:Parameter Name="id" Type="Int32" />
    </UpdateParameters>
</asp:SqlDataSource>

<ext:Store ID="Store1" runat="server" DataSourceID="SqlDataSource1"
    ShowWarningOnFailure="false"
    OnRefreshData="Store1_RefershData">
    <Reader>
        <ext:JsonReader IDProperty="id">
            <Fields>
                <ext:RecordField Name="id" />
                <ext:RecordField Name="timh" />
                <ext:RecordField Name="skeyasma" />
            </Fields>
        </ext:JsonReader>
    </Reader>
    <SortInfo Field="skeyasma" Direction="ASC" />
    <Listeners>
        <LoadException Handler="Ext.Msg.alert('Load failed', e.message || e);" />
        <CommitFailed Handler="Ext.Msg.alert('Commit failed', 'Reason: ' + msg);" />
        <SaveException Handler="Ext.Msg.alert('Save failed', e.message || e);" />
    </Listeners>  
</ext:Store>  

Το SqlDataSource σας πρέπει να έχει τα κατάλληλα SQL Queries για Insert, Delete, Update, Select. Tο Ext.Net Store τα χρησιμοποιεί αυτόματα για να υλοποιήσει όλες τις λειτουργίες CRUD. Η σύνδεση γίνεται μέσω του DataSourceID property και το grid συνδέεται με το Store μέσω του StoreID property.

Ας δούμε και τον server side event handler για το OnRefreshData event του Store. O κώδικας της Store1_RefreshData μεθόδου είναι απλός αλλά δείχνει πως μπορούμε να χειριστούμε το Ext.Net framework από το code behind (προσέξτε το απαραίτητο using statement):

using Ext.Net;
...

protected void Store1_RefershData(object sender, StoreRefreshDataEventArgs e)
{
    this.Store1.DataBind();
}

Είμαστε έτοιμοι. Έχουμε ένα grid το οποίο όχι μόνο μας παρουσιάζει δεδομένα αλλά μας επιτρέπει να προσθέσουμε, να διαγράψουμε και να τα διορθώσουμε (με διπλό κλικ σε κάθε κελί, πηγαίνουμε σε κατάσταση edit και εμφανίζεται ο κατάλληλος Editor).

Τι άλλο χρειαζόμαστε; Μια ωραία Ext.Net Toolbar με buttons που θα μας επιτρέπουν να αποθηκεύουμε τις αλλαγές, να προσθέτουμε μια νέα γραμμή δεδομένων στο grid, να σβήνουμε μια γραμμή και να ανανεώνουμε (refresh) τα δεδομένα:

<ext:Toolbar ID="Toolbar1" runat="server">
    <Items>
        <ext:Button ID="Button1" runat="server" Text="Save" Icon="Disk">
            <Listeners>
                <Click Handler="#{GridPanel1}.save();" />
            </Listeners>
        </ext:Button>
        <ext:Button ID="Button2" runat="server" Text="Delete" Icon="Delete">
            <Listeners>
                <Click Handler="#{GridPanel1}.deleteSelected();" />
            </Listeners>
        </ext:Button>
        <ext:Button ID="Button3" runat="server" Text="Insert" Icon="Add">
            <Listeners>
                <Click Handler="#{GridPanel1}.insertRecord(0, {});#{GridPanel1}.getView().focusRow(0);#{GridPanel1}.startEditing(0, 0);" />
            </Listeners>
        </ext:Button>
        <ext:Button ID="btnRefresh" runat="server"  Text="Refresh" Icon="ArrowRefresh">
            <Listeners>
                <Click Handler="#{GridPanel1}.reload();" />
            </Listeners>
        </ext:Button>
    </Items>
</ext:Toolbar>

Παρατηρήστε ότι όλες οι λειτουργίες υλοποιούνται μέσω μεθόδων του Ext.Net GridPanel (GridPanel1.save κ.ο.κ) τις οποίες καλούμε client side. Επαναλαμβάνω ότι όλα γίνονται μέσω AJAX και δεν υπάρχει κανένα postback της ASPX σελίδας.

Για λόγους εμφάνισης, το Toolbar και το GridPanel συνδιάζονται σε ένα Ext.Net Panel και το αποτέλεσμα είναι αυτό:

image

 

Μπορείτε να βρείτε το πλήρες markup (περιλαμβάνει και το Ext.Net Panel) εδώ.

Share


Έχουν δημοσιευτεί Κυριακή, 5 Φεβρουαρίου 2012 2:26 μμ από το μέλος dpant
Καταχώρηση στις κατηγορίες: ,

Σχόλια:

 

Kallanode έγραψε:

Sharp thinking! Thanks for the asnewr.

Μαρτίου 16, 2012 5:30 πμ