views:

1576

answers:

4

I thought this would be simple, but I sure am having a lot of trouble doing this:

The title of this question may be a bit misleading. I don't have to use a gridview. In fact, I know the GridView is probably not the way to go on this. I just didn't know how else to title it. But, for now just consider:

I have a very simple class called Student. It has 4 properties: int ID string FirstName string LastName string Email

I want to keep a generic collection of these in memory (session state): List students;

Ok, now the problem: I want the user to create as many of these Student objects as they want. For displaying these I just want a simple table of some kind with the 3 textboxes on each row. I would like every row to have textboxes insead of labels so that any record can be edited at anytime.

When the user is finished created their student objects, then they proceed on to do other things. But, I am just having trouble finding a way to display the records this way. Do I use the ListView(3.5), html table, gridview, repeater, etc.?

How would you do it?

+1  A: 

Yes you could use a grid view to do this. you could create a custom template for the columns so that they display in a textbox as opposed to a label. you can then capture the 'save' event an loop through the rows and update your data.

Victor
+1  A: 

Yes, this is possible. This is just a code sample for what Victor had posted.

            <asp:GridView ID="gvDetails" runat="server" AutoGenerateColumns="False" DataKeyNames="PartNumber" GridLines="Horizontal"
                ForeColor="#333333" CellPadding="4" Width="800" PageSize="20" OnDataBound="gvPartDetails_DataBound" OnSelectedIndexChanged="gvPartDetails_SelectedIndexChanged" OnSorting="gvPartDetails_Sorting">
                <Columns>
                    <asp:TemplateField HeaderText="#">
                        <ItemTemplate>
                            <asp:Label ID="lblNumber" runat="server" Text='<%# Bind("Number") %>' ToolTip='<%# Bind("Description") %>'></asp:Label>
                        </ItemTemplate>
                        <HeaderStyle Wrap="False" />
                    </asp:TemplateField>
                    <asp:TemplateField HeaderText="LOC 1">
                        <ItemTemplate>
                            <asp:TextBox ID="txt_Qty1" AutoPostBack="false" runat="server" MaxLength="5" Width="50" Text='<%# Bind("Qty1") %>'></asp:TextBox>
                        </ItemTemplate>
                        <HeaderStyle Wrap="False" />
                    </asp:TemplateField>
                    <asp:TemplateField HeaderText="LOC 2">
                        <ItemTemplate>
                            <asp:TextBox ID="txt_Qty2" AutoPostBack="false" runat="server" MaxLength="5" Width="50" Text='<%# Bind("Qty2") %>'></asp:TextBox>
                        </ItemTemplate>
                        <HeaderStyle Wrap="False" />
                    </asp:TemplateField>
                </Columns>

                <EmptyDataTemplate>
                    <span id="Empty">No Details For This Such and Such.</span>
                    <a href="javascript:showNewPartMPE();"><img src="Images/icons/table_add.png" style="border:0px" alt="Add New Part" /></a>
                </EmptyDataTemplate>

                <FooterStyle BackColor="#5D7B9D" Font-Bold="True" ForeColor="White" />
                <RowStyle BackColor="#F7F6F3" ForeColor="#333333" />
                <EditRowStyle BackColor="#999999" />
                <SelectedRowStyle BackColor="#E2DED6" Font-Bold="True" ForeColor="#333333" />
                <PagerStyle BackColor="#284775" ForeColor="White" HorizontalAlign="Center" />
                <HeaderStyle BackColor="#284775" Font-Bold="True" ForeColor="White" HorizontalAlign="Left" />
                <AlternatingRowStyle BackColor="Gainsboro" ForeColor="#284775" />
            </asp:GridView>

And then the code behind... this is very rough...

   private void ApplyChanges()
    {
        foreach (GridViewRow row in this.gvDetails.Rows)
        {
           //do something with cells and data objects
           //and then save add to list, save, etc.
        }
    }

EDIT
Above is where you will get your editing of the data. You can work with DataTables, DataViews, DataSets, and as the other solution shows, you can bind your grid to a list of your object. This should be determined based upon the data object model in your system and how the rows would be generated.

RSolberg
thanks for posting the sample code. I wasnt going to try to do so from my phone.
Victor
+1  A: 

Gridview is going to be the easiest way to implement this. You could use an html table, but when the user wants to add more users you're going to have to do a lot more. Create a template for the gridview with your four properties (Id, FirstName, LastName, Email), and then just bind it from the session object like:

public void BindGrid()
{
  // assume students is the name of your GridView control
  students.DataSource = (List<Student>)Session["StudentList"];
  students.DataBind();
}
Rorschach
+3  A: 

I would be inclined to use the ListView personally for this, since you can insert Rows with it. Your LayoutTemplate would be a table with a <tr runat="server" ID="itemPlaceHolder" /> in it. Your ItemTemplate would have your TextBox's (and optional a save button per row. Then you could have an InsertItemTemplate if you need inserts as well.

Anywhere on the page you can add a button to Save all items by looping through the ListView.Item collection and calling ListView.Update(itemIndex, validate).

<asp:ListView runat="server" ID="lv" InsertItemPosition="LastItem" DataKeyNames="id">
<LayoutTemplate>
    <asp:LinkButton runat="server" OnClick="SaveAll" Text="Save All" />
    <table>
    <tr>
     <th>First Name</th>
     <th>Last Name</th>
     <th>Email</th>
    </tr>
    <tr runat="server" id="itemPlaceHolder" />
    </table>
    <asp:LinkButton runat="server" OnClick="SaveAll" Text="Save All" />
</LayoutTemplate>
<ItemTemplate>
    <tr>
     <td><asp:TextBox runat="server" ID="firstName" Text='<%#Bind("firstName") %>' /></td>
     <td><asp:TextBox runat="server" ID="firstName" Text='<%#Bind("lastName") %>' /></td>
     <td><asp:TextBox runat="server" ID="firstName" Text='<%#Bind("email") %>' /></td>
     <td><asp:LinkButton runat="server" CommandName="update" Text="Save" /></td>
    </tr>
</ItemTemplate>
<InsertItemTemplate>
    <tr>
     <td><asp:TextBox runat="server" ID="firstName" Text='<%#Bind("firstName") %>' /></td>
     <td><asp:TextBox runat="server" ID="firstName" Text='<%#Bind("lastName") %>' /></td>
     <td><asp:TextBox runat="server" ID="firstName" Text='<%#Bind("email") %>' /></td>
     <td><asp:LinkButton runat="server" CommandName="insert" Text="Save" /></td>
    </tr>
</InsertItemTemplate>
</asp:ListView>

protected void SaveAll(object sender, EventArgs e)
{
    lv.Items.ToList().ForEach(li => lv.UpdateItem(li.DataItemIndex, true)_;
}
Josh