[ASP.Net/C#] Gridview index out of range na refresh

Pagina: 1
Acties:

Onderwerpen


Acties:
  • 0 Henk 'm!

  • PdeBie
  • Registratie: Juni 2004
  • Laatst online: 09:01
Hoi allemaal,

Ik heb een form met daarin een gridview en daaronder een placeholder waar de details van het geselecteerde record in worden getoond.

Wanneer de gebruiker een record selecteert gaat de selectedindexchange af van de gridview en worden de details keurig in de placeholder getoond. Echter als de gebruiker hierna op refresh (of F5) drukt, gaat het mis en krijg ik de volgende error: 'Index was out of range. Must be non-negative and less than the size of the collection. Parameter name: index '

Uit onderzoek blijkt dat de refresh de laatste serveractie (in dit geval de selectedindexchange) herhaalt.
Maar omdat het grid in de Page_Load gebind wordt, kloppen de indexen niet meer en gaat het dus mis.

Iemand een idee hoe ik dit kan afvangen? Het enkel tonen van het grid en de details leeg laten is in mijn ogen ook een optie, maar weet even niet hoe ik dit het beste kan aanpakken.

Acties:
  • 0 Henk 'm!

  • TeeDee
  • Registratie: Februari 2001
  • Laatst online: 17-09 23:59

TeeDee

CQB 241

Zomaar een wilde gok, maar ergens controleren of het een IsPostBack is? Wellicht dat relevante code tonen meer wonderen kan verrichten.

Heart..pumps blood.Has nothing to do with emotion! Bored


Acties:
  • 0 Henk 'm!

  • PdeBie
  • Registratie: Juni 2004
  • Laatst online: 09:01
die check zit er uiteraard in :)

Hier wat code:

C:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
protected void Page_Load(object sender, EventArgs e)
{
    if (!Page.IsPostBack)
    {
        GetMembers(String.Empty, "");
    }
}

private void GetMembers(string sortexpression, string sortdirection)
    {
        switch (rblMemberstoShow.SelectedValue)
        {
            case "P":
                //only retrieve preffered members
                List<Member> MemberList = GetPreferredMembers(sortexpression, ref sortdirection);
                gvMembers.DataSource = MemberList;
                break;
            default:
                IQueryable<Member> MemberList2 = GetAllMembers(sortexpression, ref sortdirection);
                gvMembers.DataSource = MemberList2;
                break;
        }

        gvMembers.DataBind();
    }

protected void gvMembers_SelectedIndexChanged(object sender, EventArgs e)
    {
        int memberID = -1;
        if (gvMembers.SelectedRow.Cells[0].Text.Length > 0)
            memberID = Convert.ToInt16(gvMembers.SelectedRow.Cells[0].Text);

        Member m = null;
        if (memberID > -1)
            m = new BLL().getMemberById(memberID);

        if (m != null)
        {
            phSearch.Visible = false;
            phGrid.Visible = false;
            phMemberDetail.Visible = true;

            //Member details
            MemberDetail1.member = m;
            PreferredMember pm = new BLL().getPreferredMemberById(Convert.ToInt16(getMemberNumber()), memberID);
            MemberDetail1.isPreferredMember = (pm != null);
            if (!MemberDetail1.isPreferredMember)
            {
                //Check if preferredMember exist for this city
                PreferredMember preferredMember = new DAL().getPreferredMemberByCity(Convert.ToInt16(getMemberNumber()), m.City);
                if (preferredMember != null)
                {
                    MemberDetail1.showPreferredMemberExistsWarning = true;
                    MemberDetail1.existingPrefferedMemberID = preferredMember.Member1.ID;
                }
            }
            MemberDetail1.SetMemberData(); //bind data to fields
        }
    }


de fout treedt op in regel 30 op het moment dat de gebruiker op F5 of refresh drukt.
dan geeft de site aan dat selectedindex out of range is.

Bij de eerste keer kiezen gaat het dus niet fout. Pas bij het refreshen.

vaag! :?

Acties:
  • 0 Henk 'm!

  • maniak
  • Registratie: Augustus 2000
  • Laatst online: 20-08 20:32
Is de datasource die gekoppeld is aan de gridview wel beschikbaar bij de postback?

Acties:
  • 0 Henk 'm!

  • PdeBie
  • Registratie: Juni 2004
  • Laatst online: 09:01
Ja, die is beschikbaar. Je ziet bij het debuggen ook dat er netjes records terug komen. Maar omdat de gridview opnieuw gebind wordt (regel 24), is de koppeling met de selectedindex weg.

Acties:
  • 0 Henk 'm!

  • Face_-_LeSS
  • Registratie: September 2004
  • Niet online
pdebie schreef op donderdag 21 juli 2011 @ 15:31:
... Maar omdat de gridview opnieuw gebind wordt (regel 24), is de koppeling met de selectedindex weg.
Als het goed is wordt de GridView niet opnieuw gebind voordat het SelectedIndexChanged event afgaat bij postback. Als dat wel zo is dan is dat de fout en moet de volgorde omgedraaid worden.

Acties:
  • 0 Henk 'm!

  • PdeBie
  • Registratie: Juni 2004
  • Laatst online: 09:01
in de page_load staat de functie GetMembers() waarin de databind plaats vind.
Die functie wordt alleen aangeroepen als het geen postback is.

C:
1
2
3
4
5
6
7
protected void Page_Load(object sender, EventArgs e) 
{ 
    if (!Page.IsPostBack) 
    { 
        GetMembers(String.Empty, ""); 
    } 
} 


Dus als ik een record selecteer in de gridview, komt hij niet in GetMembers() en komt hij netjes in de SelectedIndexChanged(). Dit gaat goed.

Druk ik vervolgens op F5 of de refreshknop van de browser, ziet de code dit niet als een postback en komt hij in de functie GetMembers() (waarbinnen de databind plaats vind.)

C:
1
2
3
4
5
private void GetMembers(string sortexpression, string sortdirection) 
{ 
    ... 
    gvMembers.DataBind(); 
}


Echter worden bij een refresh de laatste server acties ook herhaalt. Dit is in dit geval de SelectedIndexChanged.

Dit is toch onmogelijk om af te vangen dan?

[ Voor 18% gewijzigd door PdeBie op 22-07-2011 09:08 . Reden: code toegevoegd ]


Acties:
  • 0 Henk 'm!

  • mulder
  • Registratie: Augustus 2001
  • Laatst online: 09:56

mulder

ik spuug op het trottoir

Moet je niet nadat je de (dus in) selectedindex_changed hebt afgevangen de grid gewoon weer binden?

oogjes open, snaveltjes dicht


Acties:
  • 0 Henk 'm!

  • Face_-_LeSS
  • Registratie: September 2004
  • Niet online
Hmm, vreemd. Wat jij zegt zou normaal niet moeten gebeuren. Als je na een postback de pagina ververst (F5) dan zou de postback herhaald moeten worden. Daarom heb ik even een testje gedaan:

HTML:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="Default.aspx.cs" Inherits="WebApplication4.Default" %>

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
    <title></title>
</head>
<body>
    <form id="form1" runat="server">
    <div>
    <asp:GridView runat="server" ID="gridview" />
    </div>
    </form>
</body>
</html>


Codebehind:
C#:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
 public partial class Default : System.Web.UI.Page
    {
        protected void Page_Init(object sender, EventArgs e)
        {
            gridview.AutoGenerateSelectButton = true;
            gridview.DataKeyNames = new[] { "Name" };
            gridview.SelectedIndexChanged += new EventHandler(gridview_SelectedIndexChanged);
        }
  
        protected void Page_Load(object sender, EventArgs e)
        {
            if (!IsPostBack)
            {
                LoadData();
            }
        }

        private void LoadData()
        {
            gridview.DataSource = CultureInfo.GetCultures(CultureTypes.AllCultures);
            gridview.DataBind();
        }

        private void gridview_SelectedIndexChanged(object sender, EventArgs e)
        {
            if (gridview.SelectedRow.Cells[0].Text.Length > 0)
            {
                //....
            }
        }
    }


En dit voorbeeld werkt naar behoren. Als ik deze volgorde van acties uitvoer:

1. Initiele request
2. Regel selecteren (postback)
3. Verversen (F5)

Dan is na stap 3
1. De property "IsPostback" netjes "true"
2. Wordt de methode "LoadData" dus niet uitgevoerd
3. In de handler "gridview_SelectedIndexChanged" is de property "gridview.SelectedRow.Cells" gewoon gevuld.


Krijg je bij het verversen wel de vraag of je het formulier opnieuw wilt versturen? Deze dus:
Afbeeldingslocatie: http://www.johnsoer.com/blog/wp-content/uploads/2009/03/to_display_the_webpage_again_explorer_needs_to_resend_the_information_youve_previously_submitted.png

Werk je toevallig met dynamische controls (runtime gecreëerd)?

Acties:
  • 0 Henk 'm!

  • PdeBie
  • Registratie: Juni 2004
  • Laatst online: 09:01
Face_-_LeSS schreef op vrijdag 22 juli 2011 @ 11:05:
Krijg je bij het verversen wel de vraag of je het formulier opnieuw wilt versturen? Deze dus:
[afbeelding]

Werk je toevallig met dynamische controls (runtime gecreëerd)?
Nee die confirm krijg ik niet in beeld en maak geen gebruik van dynamische controls.

Maar schiet mij maar lek. Ik ging net weer verder met deze bug en nu werkt het naar behoren |:(
En ik heb niks aangepast 8)7 Bestandje is nog keurig ingechecked in SourceSafe.

*zoekt pistool tegen het hoofd smillie }:| *

Ik vind dit wel echt een vaag issue. IsPostback die niet als IsPostback gezien wordt. Geen confirmbox bij refresh.

Twijfel eerder of het niet in m'n markup zit.
HTML:
1
2
3
4
5
6
7
8
9
10
11
12
13
<asp:GridView ID="gvMembers" runat="server" OnRowDataBound="gvMembers_RowDataBound"
                AutoGenerateColumns="False" OnSelectedIndexChanged="gvMembers_SelectedIndexChanged"
                DataKeyNames="ID">
                <Columns>
                    <asp:BoundField DataField="ID" SortExpression="ID" />
                    <asp:BoundField DataField="Name1" HeaderText="Naam" SortExpression="Name1" />
                    <asp:BoundField DataField="Address" HeaderText="Adres" SortExpression="Address" />
                    <asp:BoundField DataField="ZipCode" HeaderText="Postcode" SortExpression="ZipCode" />
                    <asp:BoundField DataField="City" HeaderText="Plaats" SortExpression="City" />
                    <asp:BoundField DataField="Phone" HeaderText="Telefoon" SortExpression="Phone" />
                    <asp:BoundField DataField="Fax" HeaderText="Fax" SortExpression="Fax" />
                </Columns>
            </asp:GridView>
Pagina: 1