views:

856

answers:

4

Basically, i want my object back...

I have an Email object.

public class Email{
    public string emailAddress;
    public bool primary;
    public int contactPoint;
    public int databasePrimaryKey;

    public Email(){}
}

In my usercontrol, i a list of Email objects.

public List<Email> EmailCollection;

And i'm binding this to a GridView inside my usercontrol.

if(this.EmailCollection.Count > 0){
    this.GridView1.DataSource = EmailCollection;
    this.GridView1.DataBind();
}

It would be really awesome, if i could get an Email object back out of the GridView later.

How do i do this?

I'm also binding only some of the Email object's properties to the GridView as well and they're put into Item Templates.

<Columns>

<asp:TemplateField HeaderText="Email Address">
    <ItemTemplate>
        <asp:TextBox ID="TextBox1" runat="server" Text=<%# Eval("EmailAddress") %> Width=250px />
    </ItemTemplate>
</asp:TemplateField>

<asp:TemplateField HeaderText="Primary">
    <ItemTemplate>
        <asp:CheckBox runat="server" Checked=<%# Eval("PrimaryEmail") %> />
    </ItemTemplate>
</asp:TemplateField>

<asp:TemplateField HeaderText="Contact Point">
    <ItemTemplate>
        <CRM:QualDropDown runat="server" Type=ContactPoint InitialValue=<%# Eval("ContactPoint") %> />
    </ItemTemplate>
</asp:TemplateField>

</Columns>

Can GridView even do this? Do i need to roll my own thing? It'd be really cool if it would do it for me.


To elaborate more.

I am saving the List collection into the viewstate.

What I'm eventually trying to get to, is there will be a Save button somewhere in the control, which when the event fires I'd like to create an Email object from a datarow in the GridView which to compare to my original List collection. Then if there's a change, then I'd update that row in the database. I was thinking that if I could put a List collection into a GridView, then perhaps I could get it right back out.

Perhaps I create a new constructor for my Email object which takes a DataRow? But then there's a lot of complexities that goes into that...

+1  A: 

ASP.NET Databinding is a one-way operation in terms of object manipulation. However, the DataSource property will contain a reference to your EmailCollection throughout the response:

EmailCollection col = (EmailCollection)this.GridView1.DataSource;

But I have a feeling that what you really want is a control that manipulates your EmailCollection based on user input and retrieve it in the next request. Not even webforms can fake that kind of statefulness out of the box.

BC
A: 

If you want to hold onto an object like this its easiest to use the viewstate, although you will be duplicating the data but for a small object it should be ok.

ViewState.Add("EmailObj", Email);

EMail email = (Email)ViewState["EmailObj"];
Cookey
A: 

Just a thought, basically a roll your own but not that tricky to do:

Store the list that you use as a datasource in the viewstate or session, and have a hidden field in the gridview be the index or a key to the object that matches the row.

In other words, each row in the gridview "knows" which email object in the list that it is based on.

Console
+1  A: 

Well I ended up looping through my List EmailCollection, which was saved into the ViewState.

So in the page, a Save button is clicked, when the event is caught, I loop through my List Collection and grab the row from the GridView by index.

On the GridViewRow I have to use a GridView1.Rows[i].Cells[j].FindControl("myControl1") then get the appropriate value from it, be it a check box, text box, or drop down list.

I do see that a GridViewRow object has a DataItem property, which contains my Email object, but it's only available during the RowBound phase.

Unfortunately If/When i need to expand upon this Email Collection later, by adding or removing columns, it'll take a few steps.

protected void SaveButton_OnClick(object sender, EventArgs e){
    for (int i = 0; i < this.EmailCollection.Count; i++)
    {
        Email email = this.EmailCollection[i];
        GridViewRow row = this.GridView1.Rows[i];

        string gv_emailAddress = ((TextBox)row.Cells[0].FindControl("EmailAddress")).Text;
        if (email.EmailAddress != gv_emailAddress)
        {
            email.EmailAddress = gv_emailAddress;
            email.Updated = true;
        }
        ...
    }
}

I'd still be open to more efficient solutions.

Dave