SLODUG
Spletno mesto uporabniške skupine slovenskih razvijalcev programskih rešitev

GridView in editiranje nekaterih celic

ocenilo 0 uporabnikov
Rešeno (preverjeno) Ta prispevek ima 1 preverjen odgovor | 8 odgovorov | 2 sledilcev

atepina objavljeno v 07-07-2010 6:44 | Zabeleženo

Zdravo!

Zanima me ali je z gridview komponento mozno dosect to, da so le nekatere celice v vrstici readOnly, druge pa so editable?

Hvala!

Lp, A

Rešeno (preverjeno) Preverjen odgovor

Verified by atepina

Ok, štekam. Sicer meni se GridView ne zdi najbolj primeren, ker lahko to rešiš na bolj eleganten način z uporabo drugih kontrol, kjer lahko potem dodaš še kakšne JQuery cukrčke Stick out tongue

Ok, sem ti spisal primer, ki ti na podlagi XML datoteke naredi to, kar ti zahtevaš. Naredi ti vprašanje, potem odgovor z različnimi postavitvami in potem tudi preveri, ali je nekdo pravilno vnesel (validatorjev za polja nisem dodajal, lahko pa jih tudi zlahka dodaš). Primer je v ASP.NET 4, vendar ne uporabljam kakšne drastične spremembe, ki bi vplivala. Če maš VS 2008 (me zanima, zakaj ne še VS 2010 Devil), naredi nov project pa noter skopiraj kodo pa bi moralo delati. Če ne pa sporoči pa ti pretvorim v ASP.NET 3.5.

Torej; v mojem primeru mam XML, ki mi predstavlja primer tvoje zgornje križanke. Imam par razredov, ki mi služijo za shrambo podatkov in za kasnejše objektno preverjanje, vendar to ni pomembno (so helpers objekti Cool). Skratka, ideja, ki sem jo jz uporabil, se sestoji iz uporabe podatkovnih kontrolnikov DataList in Repeater kontrol (predvidevam, da bi se lahko to naredilo tudi boljše, bolj perfomančno, ampak da dobiš feeling je čisto OK). Obesim se na DataBound dogodke, kjer imam potem popolni nadzor nad tem, kaj želim v teh kontrolnikih prikazat (ima tudi referenco na moj razred, ki sem ga bindal) in potem prikažem tista polja, ki so specificirana, da niso read only (nastavim Textbox), če pa so readonly (na podlagi XML-ja), nastavim labelo.

Da je enostavneje, sem si dodal še IComparable vmesnik, da primerjam dva objekta na moj način (torej preverim, kaj je vnešeno in kaj je vnesel uporabnik). Zato da lahko to primerjam in dobim ven, sem uporabil LINQ (kok je poenostavljeno, ko uporabljaš LINQ --> število kode se drastično zmanjša pa še Resharper dobro dela s tem Geeked).

Sem ti pokomentiral vso kodo, dobiš jo pa na tem naslovu.

Če pa kaj ne razumeš pa kar vprašaj.

Lp, Bojan

Vsi odgovori

Pozdravljen!

Sure. V ta namen lahko izkoristiš že vgrajene lastnosti ReadOnly in pa templated fields, vendar te veljajo nad celotnim grid-om (gledano s strani vrstice, ko daš edit) - v vsaki vrstici je potem ta celica Read Only.

Primer:

 <asp:GridView ID="gvResult" runat="server">
        <Columns>
            <asp:BoundField HeaderText="Ime osebe" ReadOnly="true" DataField="Name" />
            <asp:BoundField HeaderText="Priimek osebe" DataField="Surname" />
            <asp:TemplateField HeaderText="Datum rojstva">
                <ItemTemplate>
                    <%#Eval("DOB","{0:d}"%>
                </ItemTemplate>
                <EditItemTemplate>
                    <asp:TextBox ID="tbDOB" runat="server" Text='<%#Bind("DOB") %>' /><br />
                    <asp:Calendar ID="calDOB" SelectedDate='<%#Eval("DOB") %>' Enabled="false" runat="server" />
                </EditItemTemplate>
            </asp:TemplateField>
        </Columns>
    </asp:GridView>

Če pa prav razumem vprašanje, bi pa rad ti naredil to, da bi imel pač random celice v fazi editiranja read only. V ta namen pa lahko izkoristiš event-e, ki jih podpira GridView pa na podlagi statusa vrstice in pogoja postaviš trenutno kontrolo v različen status.

Pač workaroundov je malo morje, vendar je vprašanje, kateri je najbolj optimalen (pri spodnjem primeru je potrebno paziti, ker je vezan na bind - če imaš kakšen ajax, moraš preveriti, če je to vključeno zraven pri prenosu na strežnik - z ajaxom lahko določiš, kaj naj se obnavlja pa kaj ne). Sporoči, če je to, kar bi rad nardil pa ti spišem en sample tega :)

protected void gvResult_RowDataBound(object sender, GridViewRowEventArgs e)
    {
        if (e.Row.RowState == DataControlRowState.Edit)
        {
            if ((e.Row.FindControl("tbNeki"as TextBox).Text.Contains("Neko Vrednost"))
            {
                (e.Row.FindControl("tbNeki"as TextBox).Enabled = false;
            }
        }
    }

Npr. par lepih primerov je tudi napisanih na MSDNju. Če sem pa narobe vprašanje razumel, me pa prosim popravi, ker včasih narobe razumem :).

Lp, Bojan

Bojan, hvala.

U bistvu je to kar bi rad naredil se najbolj podobno krizanki. Sem si pa celotno zadevo zamislil takole:

Imas grid, ki je delno izpolnjen. Celic, ki so ze izpolnjene ne mores spreminjati, celice, ki pa so prazne pa je potrebno izpolnit. Imam pa cilj, da bi stvari izpeljal tako, da bi bila stvar za uporabnika cimbolj podobna excelu - torej kliknes v prazno celico, nekaj napises, kliknes v naslednjo prazno, nekaj napises...itd. In potem na koncu pritisnes gumb submit, takrat pa bi se GridView prenesel na streznik in preveril ce je pravilno izpolnjen.

Nato pa se smetana za na vrh. V mislih sem imel, da bi se ta grid vsakic zgeneriral popolnoma nakljucno, tako da nebi bile vedno iste celice read only, ampak popolnoma nakljucno. To sploh ne vem...ali je izvedljivo ali ne. Tako nekako sem si pac zamislil :)

Se en primer podam, da bos videl, ce si prav razumel:

|  cuk  |  se  |  je  |  ozenil |  tralala  |          <-  to je vrstica ki je izpolnjena v celoti....

| ____|  se  |  je  |  ozenil | ______ |        <-  tole pa je vrstica kot bi jo videl uporabnik in bi moral prvo in zadnje polje izpolniti ( tri polja vmes so pa readonly)

 

Verjetno z samimi kontrolami tega ne bom mogel izpeljat in bom si bom moral pomagat z AJAX-om, ne?

 

Lp, Ales

Verified by atepina

Ok, štekam. Sicer meni se GridView ne zdi najbolj primeren, ker lahko to rešiš na bolj eleganten način z uporabo drugih kontrol, kjer lahko potem dodaš še kakšne JQuery cukrčke Stick out tongue

Ok, sem ti spisal primer, ki ti na podlagi XML datoteke naredi to, kar ti zahtevaš. Naredi ti vprašanje, potem odgovor z različnimi postavitvami in potem tudi preveri, ali je nekdo pravilno vnesel (validatorjev za polja nisem dodajal, lahko pa jih tudi zlahka dodaš). Primer je v ASP.NET 4, vendar ne uporabljam kakšne drastične spremembe, ki bi vplivala. Če maš VS 2008 (me zanima, zakaj ne še VS 2010 Devil), naredi nov project pa noter skopiraj kodo pa bi moralo delati. Če ne pa sporoči pa ti pretvorim v ASP.NET 3.5.

Torej; v mojem primeru mam XML, ki mi predstavlja primer tvoje zgornje križanke. Imam par razredov, ki mi služijo za shrambo podatkov in za kasnejše objektno preverjanje, vendar to ni pomembno (so helpers objekti Cool). Skratka, ideja, ki sem jo jz uporabil, se sestoji iz uporabe podatkovnih kontrolnikov DataList in Repeater kontrol (predvidevam, da bi se lahko to naredilo tudi boljše, bolj perfomančno, ampak da dobiš feeling je čisto OK). Obesim se na DataBound dogodke, kjer imam potem popolni nadzor nad tem, kaj želim v teh kontrolnikih prikazat (ima tudi referenco na moj razred, ki sem ga bindal) in potem prikažem tista polja, ki so specificirana, da niso read only (nastavim Textbox), če pa so readonly (na podlagi XML-ja), nastavim labelo.

Da je enostavneje, sem si dodal še IComparable vmesnik, da primerjam dva objekta na moj način (torej preverim, kaj je vnešeno in kaj je vnesel uporabnik). Zato da lahko to primerjam in dobim ven, sem uporabil LINQ (kok je poenostavljeno, ko uporabljaš LINQ --> število kode se drastično zmanjša pa še Resharper dobro dela s tem Geeked).

Sem ti pokomentiral vso kodo, dobiš jo pa na tem naslovu.

Če pa kaj ne razumeš pa kar vprašaj.

Lp, Bojan

Malce pozno odgovarjam - dopust :) Bojan hvala!

Vidis, Repeaterja in Datalista sploh nikoli nisem uporabljal, nekako nisem nasel pravega primera zanju. No zdej vidim, da sta se kako uporabna. Linq pa res zmanjsa stevilo vrstic v kodi. Zdaj moram le se pogruntat sistem, da podatki o tem, ali je beseda readonly ali ne, ne bodo hardcodani, ampak bodo dinamicno doloceni in bodo vsakic drugacni (kot neke vrste test). No...ce ne bo slo, bom povprasal. Ce pa imas kak nasvet / namig, ga bom pa zelo vesel.

Lp, A

v bistvu če pogledaš sample, maš v XML-u (krizanka.xml) definirano, kaj je readonly in kaj ne....in na podlagi tega se ti zgenerirajo textbox-i...maš pa helper class-e, da se ti ni treba ukvarjat z xml-om, ampak se ukvarjaš z objekti. XML lahko nadomestiš z bazo, web servis-om, itd. pa boš mel isto funkcionalnost. Samo spremen helper objekte, da berejo od drugod pa si zmagal.

Če maš pa kako specifičnost pa kr sporoči pa bomo pogledali, kaj se da naredit.

Lp, Bojan

bak3r V odgovor na 10-04-2010 14:18 | Zabeleženo

Jaz imam pa en podoben problem. Imam datalist v katerem imam repeater. V repeaterju je pa textbox. Datalist ima eno metodo OnItemDataBound in tudi repeater ima eno metodo OnItemDataBound.

V prvem primeru (datalist - onitemdatabound) poiscem repeater in bindam na nek datasource.

V drugem primeru (repeater - onitemdatabound) pa poiscem textbox mu dodam en tekst in nekaterim nastavim vrednost readonly na true, nekaterim pa na false.

Namen je...da uporabnik izpolni tiste textboxe, ki niso readonly in submita odgovore.

Problem je, da ob postbacku ne dobim vrednosti, ki jih je uporabnik vpisal. Dobim lahko tiste, ki sem jih jaz nastavil tekstboxom, ostale pa so kar prazne. Kaj bi lahko bilo narobe?

 

bak3r V odgovor na 10-04-2010 14:23 | Zabeleženo

Pa se koda...kako pridobivam vrednost tekstboxev ob postbacku:

foreach(Repeater items in from DataListItem currentItem in datalistWords.Items select currentItem.FindControl("repeaterWord") as Repeater)
{
    foreach(RepeaterItem currentRepeaterItem in items.Items)
    {
        TextBox txtBx = currentRepeaterItem.FindControl("txtBx") as TextBox;
        Reponse.Write(txtBx.Text);
    }
}

Suggested by bojanv

Problem je, ker dinamično dodajaš zadeve, se stanje ne ohranja. Tale trick ti zna pridt prav (na spletni strani):

protected override object SaveViewState()
        {
            return new Pair(base.SaveViewState(), null);
        }

        protected override void LoadViewState(object savedState)
        {
            base.LoadViewState(((Pair)savedState).First);
            EnsureChildControls();
        }

Sporoči, če ti to reši problem. Če ne, bomo pa malce debugali. Smile

Lp, Bojan

Stran 1 od 1 (9 predmetov) | RSS
© 2004-2008 SLODUG
Powered by Community Server (Commercial Edition), by Telligent Systems