Link to home
Start Free TrialLog in
Avatar of allanmark
allanmark

asked on

ObjectDataSource returns same record to FormView

Greetings all,

I have a page that has a listbox containing "Couple" names and a FormView (fvSpousal) that provides the Couple
details (the listbox is bound to a List that holds the couple name and Id -- used to get the couple details).
I am using an ObjectDataSource, defined in Source (see attached code), tied to a method in the BusinessLayer, which returns a DataTable, containing the Couple's details.

A method (GetCoupleDetails) sets the SelectrPrameter value and then calls DataBind, which in turn results in the BusinessLayer method being called.

When the user clicks on a name in the listbox, the appropriate details should end up in the FormView.

At the moment, regardless of what name is selected, the first couples details always appear (placing a break on the BusinessLayer method, I can see that the parameter value has changed to that of the first name).

Any suggestions?


In advance, thanks!!!

   allanmark


SOURCE:
 
        <asp:FormView  ID="fvSpousal" runat="server" DefaultMode="ReadOnly" OnDataBound="fvSpousal_DataBound" DataSourceID="myODS"
                EnableViewState="true" DataKeyNames="C_Id" CssClass="smallFontSize" OnModeChanging="fvSpousal_ModeChanging" 
                OnItemCommand="fvSpousal_ItemCommand" OnItemUpdating="FvSpousal_ItemUpdating" >  
                         
            <ItemTemplate>
........................
..........................
 
 
CODE BEHIND (BUSINESS LAYER):
 
 public static DataTable GetCouple(int coupleId)
        {
            DataTable dtOurCouple = new DataTable();
            dtOurCouple = DataAccess.ReturnCouple(coupleId);            
            return dtOurCouple;
        }
 
 
CODE BEHIND (PAGE):
 
public partial class People : System.Web.UI.Page
{
    ....................
    private bool coupleIsFound;
 
    protected void Page_Load(object sender, EventArgs e)
    {
        if (Page.IsPostBack)
        {
            if (Session["portfolios"] != null)
            {
                dtThePortfolios = (DataTable)Session["portfolios"];
            }
            else
            {
                GetPortfolios();
            }
 
            if (Session["titles"] != null)
            {
                dtTheTitles = (DataTable)Session["titles"];
            }
            else
            {
                GetTitles();
            }
 
            if (Session["couples"] != null)
            {
                Session["selectedCouple"] = lbxCouples.SelectedIndex;
                couplesList = (List<CoupleName>)Session["couples"];
                lbxCouples.DataSource = couplesList;
                lbxCouples.DataTextField = "Name";
                lbxCouples.DataValueField = "Id";
                lbxCouples.DataBind();
                lbxCouples.SelectedIndex = (int)Session["selectedCouple"];
 
                //if (Session["theCouple"] != null)
                if (Session["ods"] != null)
                {
                    myODS = (ObjectDataSource)Session["ods"];
                }
                else
                {
                    GetCoupleDetails(couplesList[lbxCouples.SelectedIndex].Id);
                }
            }
            else
            {
                GetCouples();
            }
        }
        else
        {
            // Not PostBack.
 
            GetPortfolios();
            GetTitles();
 
            GetCouples();                        
            Session["selectedCouple"] = lbxCouples.SelectedIndex;
           
        }
    }
 
    protected void fvSpousal_ItemCommand(object sender, FormViewCommandEventArgs e)
    {
        switch (e.CommandName.ToUpper())
        {
            case "EDIT":
                pnlSelector.Enabled = false;
                fvSpousal.ChangeMode(FormViewMode.Edit);
                fvSpousal.DataBind();
 
                break;
            case "INSERT":
                pnlSelector.Enabled = false;
                fvSpousal.ChangeMode(FormViewMode.Insert);
                fvSpousal.DataBind();
                break;
            case "UPDATE":
 
                break;
        }
    }
 
    protected void FvSpousal_ItemUpdating(Object sender, FormViewUpdateEventArgs e)
    {
        // Todo: No validating (fields present, dates, etc will be done for the prototype.
        //       This will be implemented in Phase 2.
        DropDownList ddlPortF_CE = fvSpousal.FindControl("ddlPortfolio_CE") as DropDownList;
	..........        
    }
 
    /// <summary>
    /// The couple names for the ListBox.
    /// </summary>
    protected void GetCouples()
    {
        couplesList = BusinessLogic.Business.GetCoupleNames(chkActive.Checked, chkInvolved.Checked);
        couplesList.Sort();
        lbxCouples.DataSource = couplesList;
        lbxCouples.DataTextField = "Name";
        lbxCouples.DataValueField = "Id";
        lbxCouples.DataBind();
        lbxCouples.SelectedIndex = 0;
        Session["couples"] = couplesList;
        Session["selectedCouple"] = lbxCouples.SelectedIndex;
 
        if (lbxCouples.Items.Count > 0)
        {
            GetCoupleDetails(couplesList[lbxCouples.SelectedIndex].Id);
        }
    }
 
    protected void GetCoupleDetails(int coupleId)
    {       
        myODS.SelectParameters["CoupleId"].DefaultValue = coupleId.ToString();
        fvSpousal.DataBind();
        Session["ods"] = myODS;
 
        //if (theCouple != null)
        if (coupleIsFound)
        {
            Button btnEd = fvSpousal.FindControl("btnEditI") as Button;
            btnEd.Enabled = true;
            Button btnDel = fvSpousal.FindControl("btnDeleteI") as Button;
            btnDel.Enabled = true;
        }
        else
        {
            ScriptManager.RegisterStartupScript(Page, this.GetType(), "id", "alert('Couple record not found. Please contact the Sytem Administrator.');", true);
            lbxCouples.SelectedIndex = 0;
        }
        SetUpdatePanels();
 
    }
 
    protected void fvSpousal_DataBound(object sender, EventArgs e)
    {
        // Todo:  With all this repetition, is there not a generic method that we can develop and
        //        just pass it parameters?
 
        // For the ItemTemplate:
 
        DataRowView drv = (DataRowView)fvSpousal.DataItem;
        
        switch (fvSpousal.CurrentMode)
        {
            case FormViewMode.ReadOnly:
                // Portfolio dropdown for couple
                DropDownList ddlPortF_CI = fvSpousal.FindControl("ddlPortfolio") as DropDownList;
                ddlPortF_CI.DataSource = dtThePortfolios;
                ddlPortF_CI.DataTextField = "PF_Title";
                ........................
                ..............................
                break;
        } // switch (fvSpousal.CurrentMode)
    }
 
    protected void lbxCouples_SelectedIndexChanged(object sender, EventArgs e)
    {
        GetCoupleDetails(couplesList[lbxCouples.SelectedIndex].Id);
        Session["selectedCouple"] = lbxCouples.SelectedIndex;
    }
 
    protected void myODS_Selected(object sender, ObjectDataSourceStatusEventArgs e)
    {
        .......................)
    }
 
}

Open in new window

Avatar of GuitarRich
GuitarRich
Flag of United Kingdom of Great Britain and Northern Ireland image

It looks to me like you make be doing some work twice in there.  In the SelectedIndexChanged event you are setting the Session["selectedCouple"] and calling GetCoupleDetails() - but you are also doing this in the postback section of the Page_Load event. Try commenting out lines 53-69. I don't think you need to re-load the data into the listbox on the postback and this might be what is resetting the selected index causing you to always get the first couples details.
Avatar of allanmark
allanmark

ASKER

Hi!

I commented out the lines and it fell over in the SelectIndexChanged when trying to call GetCoupleDetails -- null instance of the object).

I uncommenetd the lines and put a break on 68 -- it is never executed (shoudl only be executed if the session object is missing).

It is definitelt doing something twice - a break on the GetCouple (business layer) confirms this.
So, I placed a break on line 142 and guess what - before executing the databind , it is calling the Busineslayer routine - ie, the parameter change is forcing the call to the BL method.

Does this make any kind of sense?
So when you click on a couple and it fires SelectedIndexChanged the GetCouples method is called before the SelectedIndexChanged event is called? Can you look at the stack trace and see where that is being called from?
I would assume its somewhere in the logic for the Page_Load as this will get called before the event method is called.
When it fell over was it the selected index that was null or the ObjectDataSource? If it was the ODS try commenting lines 55-59 so you are not re-binding the listbox every time the page is posted back.
also - when you step into the SelectedIndexChanged event - what is the selectedindex? is it always the first entry?
Sorry ... I'm probably not been very clear ... the Listbox has a different datasource (a <List>).

When I step into SelectedIndexCHanged, the Index is that of the newly selected listbox entry, ( ie the one that I ahve just clciked on).

>>So when you click on a couple and it fires SelectedIndexChanged the GetCouples method is >>called before the SelectedIndexChanged event is called?
No.  GetCoupleDetails is called from The SelectedIndexChanged event (stepped through to confirm). Once inside GetCoupleDetails, the parameter change triggers the call to the BusinessLayer method. The SelectParameter, BTW, has the Id of the newly selected COuple.

Diigng around, I found this:

AFAIK, if you change any value of the SelectParameters or FilterParameters, the ObjectDataSource will set an internal flag to rebind on the PreLoad stage. However, if it's the first time that the page was requested this flag is set to true, so it will fetch the data only once.

From here:
http://www.codenewsgroups.net/group/microsoft.public.dotnet.framework.aspnet.webcontrols/topic10502.aspx
ASKER CERTIFIED SOLUTION
Avatar of GuitarRich
GuitarRich
Flag of United Kingdom of Great Britain and Northern Ireland image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Tks!

WIll try that and post back results.
Ok.

Changed everythign to programamtically to the ODS and it solves the problem.

Sadly, it creates another issue  -- the Old/NewValues available as part of the FormViewUpdateEventArgs in the ItemUpdating event are not null.

I really don't weant to do the "Textbox abc = (TextBox(FvSposual.FindControl(....." thingy because there are soemthing like 30 controls involved.

Any suggestion?

Seems like you must change teh parameters in the _Selecting Event  -- as per this article:
http://weblogs.asp.net/rajbk/pages/426642.aspx   -- will post back later.
That pretty much does it!!

Many thanks for your help!