Avatar billede muggen Nybegynder
08. februar 2006 - 15:51 Der er 41 kommentarer og
1 løsning

Problemer med valg af row i gridview når jeg bruger paging

Jeg har et gridview og et detailsview ved siden af hinanden i Visual Studio 2005 (ASP.NET 2.0). Jeg opretter nye records i detailsview. Når jeg opretter en ny record i detailsview bruger jeg ItemInserted eventen til binde til data igen så gridview'et bliver opdateret og sikre mig at den nyindatte record bliver valgt i grid'et:

public void UsersDetail_ItemInserted(object sender,
  DetailsViewInsertedEventArgs e)
    {
        String userAddedUserID = e.Values["UserID"].ToString();
        String userAddedName = e.Values["Name"].ToString();

        GridView1.DataBind();

        foreach (GridViewRow r in GridView1.Rows)
        {
          if (r.Cells[1].Text.TrimEnd(null) == userAddedUserID)
            {
                GridView1.SelectedIndex = r.RowIndex;
                break;
            }
        }

        lblMessage.Text = "You have successfully added " + userAddedName + " to the list of users!";
    }

Det virker fint lige indtil jeg slår paging til. I mit grid har jeg valgt kun at vise 20 records af gangen. Mit problem er, at hvis jeg vælger en af de første 20 records og ser den i detailsview og her klikker på "Add new user" og den nye "user" ikke bliver placeret blandt de 20 første i gridview'et pga. sortering, så bliver den nyindsatte "user" ikke valgt. Hvordan løser jeg dette problem?
Avatar billede dr_chaos Nybegynder
08. februar 2006 - 16:04 #1
prøv noget med:
GridView1.PageIndex = (r.RowIndex/GridView1.PageCount)
Avatar billede muggen Nybegynder
08. februar 2006 - 16:11 #2
Det virker stadigvæk ikke. jeg har erstattet

GridView1.SelectedIndex = r.RowIndex;

med

GridView1.PageIndex = (r.RowIndex/GridView1.PageCount)
Avatar billede dr_chaos Nybegynder
08. februar 2006 - 16:16 #3
du skal ikke erstatte du skal kombinere.
Muligvis skal den rettes lidt til

if (r.Cells[1].Text.TrimEnd(null) == userAddedUserID)
            {
                GridView1.SelectedIndex = r.RowIndex;
                GridView1.PageIndex = (r.RowIndex/GridView1.PageCount)
                break;
            }
Avatar billede dr_chaos Nybegynder
08. februar 2006 - 16:22 #4
i følge de test udregninger jeg har lavet burde det virke.
Avatar billede muggen Nybegynder
08. februar 2006 - 16:27 #5
Det virker desværre ikke. Det er stadigvæk den record som jeg starter med at vælge blandt de 20 første records der er valgt efter jeg har tilføjet en ny. Indsætter jeg en ny record som bliver vist blandt de 20 første virker det fint.
Avatar billede dr_chaos Nybegynder
08. februar 2006 - 16:38 #6
kommer du ind i if sætningen ?
Avatar billede muggen Nybegynder
08. februar 2006 - 16:49 #7
Ja, og den løber også fint igennem de enkelte records og rammer break; når GridView1.SelectedIndex = r.RowIndex;
Avatar billede muggen Nybegynder
08. februar 2006 - 16:56 #8
Passer ikke helt hvad jeg sagde. Efter de 20 første records springer den ud af it sætningen. I første omgang kon jeg til at indsætte en record som var blandt de 20 første og der virkede det fint.
Avatar billede dr_chaos Nybegynder
08. februar 2006 - 16:57 #9
Prøv at hardcode GridView1.PageIndex i page load.
F.eks at sætte den til 2.
Avatar billede muggen Nybegynder
08. februar 2006 - 17:09 #10
Det er den ligeglad med. Jeg hæftede mig også ved det før da jeg debuggede da bookAddedID og Cells[1].Text var lig med hinaden. Her var
GridView1.SelectedIndex 7
r.rowindex 2
GridView1.PageCount 2
og
GridView1.PageIndex 0

Men sådan skulle det måske se ud?
Avatar billede dr_chaos Nybegynder
08. februar 2006 - 17:14 #11
jeg lavede ihvertifald  en fejl.
prøv med


public void UsersDetail_ItemInserted(object sender,
  DetailsViewInsertedEventArgs e)
    {
        String userAddedUserID = e.Values["UserID"].ToString();
        String userAddedName = e.Values["Name"].ToString();

        GridView1.DataBind();

        foreach (GridViewRow r in GridView1.Rows)
        {
          f (r.Cells[1].Text.TrimEnd(null) == userAddedUserID)
            {
                GridView1.PageIndex = (r.RowIndex/GridView1.PageSize)
                GridView1.SelectedIndex = r.RowIndex;

                break;
            }
        }

        lblMessage.Text = "You have successfully added " + userAddedName + " to the list of users!";
    }
Avatar billede muggen Nybegynder
08. februar 2006 - 17:27 #12
hmmm - virker stadigvæk ikke.
Avatar billede dr_chaos Nybegynder
08. februar 2006 - 17:30 #13
paste lige din codebehind.
Avatar billede muggen Nybegynder
08. februar 2006 - 17:43 #14
Her er den. Det er for denne eventhanler jeg roder med det og ikke den vi har kigget på indtil videre, men det burde ikke gøre deb store foreskel.
   
    public void BookDetail_ItemUpdating(object sender,
    DetailsViewUpdateEventArgs e)
    {
        if (e != null && e.NewValues != null && e.NewValues["Title"] == null)
        {
            e.Cancel = true;

            lblValidation.Text = "Please fill in a book title.";
        }
    }
   
    //The BookDetail_ItemInserted event handler is used to handle the DetailsView ItemInserted
    //event. The ItemInserted event occurs when the "Add new book" button is clicked, but after the insert operation.
    public void BookDetail_ItemInserted(object sender,
    DetailsViewInsertedEventArgs e)
    {
      String bookAddedID = e.Values["BookID"].ToString();
       
      String bookAddedTitle = e.Values["Title"].ToString();
       
      GridView1.DataBind();
       
       
        foreach (GridViewRow r in GridView1.Rows)
        {
            if (r.Cells[1].Text.TrimEnd(null) == bookAddedID)
            {
                GridView1.PageIndex = (r.RowIndex/GridView1.PageSize);
                GridView1.SelectedIndex = r.RowIndex;

                break;
            }
        }

                lblMessage.Text = "You have successfully added " + bookAddedTitle + " to the list of books!";
Avatar billede muggen Nybegynder
08. februar 2006 - 17:44 #15
Ahh - der gik et eller andet galt - øjeblik.
Avatar billede muggen Nybegynder
08. februar 2006 - 17:46 #16
Her er den:

public void BookDetail_ItemInserted(object sender,
    DetailsViewInsertedEventArgs e)
    {
       
        String bookAddedID = e.Values["BookID"].ToString();
       
        String bookAddedTitle = e.Values["Title"].ToString();
       
        GridView1.DataBind();
       
       
        foreach (GridViewRow r in GridView1.Rows)
        {
            if (r.Cells[1].Text.TrimEnd(null) == bookAddedID)
            {
                GridView1.PageIndex = (r.RowIndex/GridView1.PageSize);
                GridView1.SelectedIndex = r.RowIndex;

                break;
            }
        }

       
        lblMessage.Text = "You have successfully added " + bookAddedTitle + " to the list of books!";
    }
Avatar billede dr_chaos Nybegynder
08. februar 2006 - 17:49 #17
kalder du GridView1.DataBind(); andre steder ?
Avatar billede muggen Nybegynder
08. februar 2006 - 17:52 #18
Ja, den kalder jeg faktisk i alle mine forskellige event handlers, bl.a. i BookDetail_ItemInserting som jeg bruger til at validere for ikke udfyldte textboxes.
Avatar billede dr_chaos Nybegynder
08. februar 2006 - 17:56 #19
du kalder den vel ikke i pageload eller lignende ?
Avatar billede muggen Nybegynder
08. februar 2006 - 17:57 #20
Nej!
Avatar billede dr_chaos Nybegynder
08. februar 2006 - 18:18 #21
prøv at udskrive selected index i page load for at se om det skifter
Avatar billede muggen Nybegynder
09. februar 2006 - 08:19 #22
Når jeg gør følgende i page load:

GridView1.PageIndex = 2;
GridView1.SelectedIndex = 2;

opfører den sig helt som som man vil forvente. Den viser side 2 og den vælger den 3. record i grid'et.

Skal jeg ikke på en eller anden måde have sat pageindex før jeg går igennem min foreach statement? Den springer jo ud af foreach statement'en efter de første 20 records.
Avatar billede dr_chaos Nybegynder
09. februar 2006 - 08:23 #23
du ved jo ikke hvad pageindex er før du har fundet den indsatte record.
Løber foreach sætningen aldrig mere end 20 rows igennem ?
Avatar billede muggen Nybegynder
09. februar 2006 - 08:43 #24
Nej, den springer ned til min lblMessage efter de den har løbet igennem de 20 første records, hvilket vil sige at

GridView1.PageIndex = (r.RowIndex/GridView1.PageSize);
                GridView1.SelectedIndex = r.RowIndex;

                break;

aldrig bliver kørt, vel?
Avatar billede dr_chaos Nybegynder
09. februar 2006 - 08:53 #25
ja.
prøv at sætte GridView1.PageIndex = 2;
over foreach sætningen.
Avatar billede muggen Nybegynder
09. februar 2006 - 08:59 #26
Hvis jeg gør det, så får jeg en "Exception of type 'System.OutOfMemoryException' was thrown" fejlbesked.
Avatar billede dr_chaos Nybegynder
09. februar 2006 - 09:01 #27
hmm jeg har læst lidt mere op på gridview.
Jeg tror problemet er at rowcollection ikke er større end 20.
Avatar billede dr_chaos Nybegynder
09. februar 2006 - 09:01 #28
og derfor henter den ikke flere end de 20 første p.ga. paging.
Avatar billede muggen Nybegynder
09. februar 2006 - 09:04 #29
Det var også det jeg selv var nået frem til, men hvordan får jeg den til at løbe igennem alle rows og ikke kun de 20 som er styret af paging?
Avatar billede dr_chaos Nybegynder
09. februar 2006 - 09:10 #30
bruger du objectdatasource eller sqldatasource ?
Avatar billede muggen Nybegynder
09. februar 2006 - 09:11 #31
sqldatasourse
Avatar billede dr_chaos Nybegynder
09. februar 2006 - 09:12 #32
det er desværre det som er problemet.
Avatar billede dr_chaos Nybegynder
09. februar 2006 - 09:13 #33
som ms skriver :
The downside of using a SqlDataSource as a pageable GridView's data source control is that the GridView uses the default paging model. That is, on each page request the SqlDataSource returns all of the records that are to be paged through to the GridView. The GridView then picks out the correct subset of records based on the number of records to show per page and the page index. In order to implement the custom paging model you'll need to use an ObjectDataSource.
Avatar billede muggen Nybegynder
09. februar 2006 - 09:20 #34
Har du ms referencen (link) til ovenstående og er der yderligere eksempler på hvordan man så bruger ObjectDataSource i forhold til ovenstående beskrivelse?
Avatar billede dr_chaos Nybegynder
09. februar 2006 - 09:24 #35
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dnaspp/html/GridViewEx05.asp
før din foreach sætning prøv da at udskrive GridView1.Rows.Count og se hvad du får.
Avatar billede muggen Nybegynder
09. februar 2006 - 09:35 #36
Jeg var lidt hurtig før da jeg sagde at jeg fik den exception - det var noget andet kode der genererede den fejl. Det virker fint når jeg sætter GridView1.PageIndex = 2; før foreach statement'en.

Ved GridView1.Rows.Count får jeg som ventet 20!
Avatar billede dr_chaos Nybegynder
09. februar 2006 - 09:39 #37
Du kan gøre det på en anden måde.
Ved at lave en select på sqldatasource og løbe det resulterende dataview igennem og beregne det pageindex som posten ligger på.
Det skal gøre før din foreach sætning.
Avatar billede muggen Nybegynder
10. februar 2006 - 11:06 #38
Jeg er "lost". Jeg famler i blinde. Jeg har prøvet mange forskellige ting, men det vil bare ikke som jeg vil. Kan du prøve at give et løsningsforslag som bygger på dit forslag oven over - bare så jeg kan komme i gang derfra.
Avatar billede muggen Nybegynder
14. februar 2006 - 13:45 #39
Har fundet på en løsning der virker, men kan ikke gennemskue om det er en optimal løsning:

public void BookDetail_ItemInserted(object sender,
    DetailsViewInsertedEventArgs e)
    {
       
        String bookAddedID = e.Values["BookID"].ToString();
       
       
        String bookAddedTitle = e.Values["Title"].ToString();
       
       
        int index = GetRowIndex(bookAddedID);

       
        GridView1.PageIndex  = (index / GridView1.PageSize);

       
        GridView1.DataBind();

       
        foreach (GridViewRow r in GridView1.Rows)
        {
            if (r.Cells[1].Text == bookAddedID)
            {
                //GridView1.PageIndex = (r.RowIndex / GridView1.PageSize);
                GridView1.SelectedIndex = r.RowIndex;

                break;
            }
        }

       
        lblMessage.Text = "You have successfully added " + bookAddedTitle + " to the list of books!";
    }

    private int GetRowIndex(string bookID)
    {
        SqlDataSource sql = SqlDataSource1;
        DataView list = sql.Select(new DataSourceSelectArguments()) as DataView;
        DataRowCollection rows = list.Table.Rows;
        int i = 0;

        foreach (DataRow row in rows)
        {
            if (string.Compare(row["BookID"].ToString(), bookID) == 0)
                return i;
            i++;
        }

        return -1;
    }
Avatar billede dr_chaos Nybegynder
14. februar 2006 - 17:05 #40
det tror jeg det var også noget i den stil jeg havde tænkt mig
Avatar billede muggen Nybegynder
15. februar 2006 - 08:14 #41
Send som svar dr chaos, så får du dine point. Det var dig, der satte mig på sporet. Tak for hjælpen.
Avatar billede dr_chaos Nybegynder
15. februar 2006 - 08:15 #42
svar :)
Avatar billede Ny bruger Nybegynder

Din løsning...

Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] Web- og emailadresser omdannes automatisk til links. Der sættes "nofollow" på alle links.

Loading billede Opret Preview
Kategori
IT-kurser om Microsoft 365, sikkerhed, personlig vækst, udvikling, digital markedsføring, grafisk design, SAP og forretningsanalyse.

Log ind eller opret profil

Hov!

For at kunne deltage på Computerworld Eksperten skal du være logget ind.

Det er heldigvis nemt at oprette en bruger: Det tager to minutter og du kan vælge at bruge enten e-mail, Facebook eller Google som login.

Du kan også logge ind via nedenstående tjenester