CodeBetter.Com
CodeBetter.Com
RSS 2.0 via Feedburner
           Do you Twitter? Follow us @CodeBetter

Jay Kimble -- The Dev Theologian

Philosophizing about the .Net religion

Unbound GridView

This post will show you how to create a simple unbound GridView with Edit, Update, Cancel, and Add capabilities.  I need this post for my own memory.  Maybe it will help you, too. Here's my simple ASP.NET Gridview's HTML (using templated columns):

<asp:GridView ID="gvMyGrid" runat="server" 
            
AutoGenerateColumns="False" ShowFooter="True" OnRowCommand="gvMyGrid_RowCommand" 
            OnRowUpdating="
gvMyGrid_RowUpdating" OnRowEditing="gvMyGrid_RowEditing" OnRowCancelingEdit="gvMyGrid_RowCancelingEdit">         <Columns>
            <asp:TemplateField ShowHeader="False">
                <EditItemTemplate>
                    <asp:LinkButton ID="LinkButton1" runat="server" CausesValidation="True" CommandName="Update"
                        Text="Update"></asp:LinkButton>
                    <asp:LinkButton ID="LinkButton2" runat="server" CausesValidation="False" CommandName="Cancel"
                        Text="Cancel"></asp:LinkButton>
                </EditItemTemplate>
                <ItemTemplate>
                    <asp:LinkButton ID="LinkButton1" runat="server" CausesValidation="False" CommandName="Edit"
                        Text="Edit"></asp:LinkButton>
                </ItemTemplate>
                <FooterTemplate>
                    <asp:LinkButton ID="linkAdd" runat="server" CommandName="ADD">Add</asp:LinkButton>
                </FooterTemplate>
            </asp:TemplateField>
            <asp:TemplateField HeaderText="SomeID" SortExpression="
SomeID">
                <EditItemTemplate>
                    <asp:Label ID="lbl
SomeID" runat="server" Text='<%# Bind("SomeID") %>'></asp:Label>
                </EditItemTemplate>
                <ItemTemplate>
                    <asp:Label ID="lbl
SomeID" runat="server" Text='<%# Bind("SomeID") %>'></asp:Label>
                </ItemTemplate>
            </asp:TemplateField>
            <asp:TemplateField HeaderText="
SomeText" SortExpression="SomeText">
                <EditItemTemplate>
                    <asp:TextBox ID="txt
SomeText" runat="server" Text='<%# Bind("SomeText") %>'></asp:TextBox>
                </EditItemTemplate>
                <ItemTemplate>
                    <asp:Label ID="lbl
SomeText" runat="server" Text='<%# Bind("SomeText") %>'></asp:Label>
                </ItemTemplate>
                <FooterTemplate>
                    <asp:TextBox ID="txtNew
Text" runat="server"></asp:TextBox>
                </FooterTemplate>
            </asp:TemplateField>
        </Columns>
        <EmptyDataTemplate>
            <table><tr><td><asp:LinkButton ID="linkAddEmptyTemplate" runat="server" CommandName="ADD_FROMEMPTY">Add</asp:LinkButton></td><td>&nbsp;Desc:</td><td><asp:TextBox ID="txtNewText_
FROMEMPTY" runat="server"></asp:TextBox></td></tr></table>
        </EmptyDataTemplate>
    </asp:GridView>
Ok, so we have a gridview with an uneditable ID and a Text Field. 

Tearing this a apart a bit.  We put an extra row in the footer that contains an extra Text field and an Add button.  We also have a table containing another Add button and a Text Field in the EmptyDataTemplate.  This means that we will always have an add option.

So here's the code (again this is a simple example) that makes this all work (yep, it's C# <grin />):
protected void Page_Load(object sender, EventArgs e)
    {
        if (!IsPostBack)
        {
            BindGidData();
        }
       // default the footer to visible
        gvMyGrid.ShowFooter = true;
    }
    // Binds data for the entire example
    protected void BindGridViewData()
    {
         // TODO: Substitute your own DataObject and RetrievalRoutine
         MyDataObject obj = SomeClass.SomeRoutineToGetData();
         gvMyGrid.DataSource = obj;
         gvMyGrid.DataBind();
     }

// called by the front end when a linkbutton is pushed
protected void gvMyGrid_RowCommand(object sender, GridViewCommandEventArgs e)
    {
        if (e.CommandName.Substring(0,3) == "ADD")
        {
            string SomeText = "";
            // based on the Command name retrieve the data
            if(e.CommandName == "ADD")
            {
                SomeText = ((TextBox)gvMyGrid.FooterRow.FindControl("txtNewText")).Text;
            }
            else
            {
                // This was a piece of voodoo that I had to figure out.
                // when the grid is empty
                //    gvMyGrid.Controls[0].Controls[0] will be a GridViewRow containing the controls
                //     in the empty data template
.                 SomeText = ((TextBox)((GridViewRow)gvMyGrid.Controls[0].Controls[0]).FindControl("txtNewDescription_FROMEMPTY")).Text;
            }
            // TODO: add code to do your actual insert
            BindGridViewData();
        }
    }

    // Called when the record will be edited.  You need to manually set the edit index
    protected void gvMyGrid_RowEditing(object sender, GridViewEditEventArgs e)
    {
        gvMyGrid.EditIndex = e.NewEditIndex;
        gvMyGrid.ShowFooter = false; // We also turn off the add screen while updating data
        BindGridViewData();
    }

        // Fires when the Cancel button is clicked
    protected void gvMyGrid_RowCancelingEdit(object sender, GridViewCancelEditEventArgs e)
    {
        gvMyGrid.EditIndex = -1;
        BindGridViewData();
    }

    // This record fires when the Update button is clicked
    protected void gvMyGrid_RowUpdating(object sender, GridViewUpdateEventArgs e)
    {
           // use the EditIndex property and the rows collection to retrieve a reference tot he individual edit controls
            int SomeID = Convert.ToInt32(((Label)((gvMyGrid.Rows[gvMyGrid.EditIndex].Cells[1].FindControl("lblSomeID")))).Text)
           string SomeText  = ((TextBox)((gvMyGrid.Rows[gvMyGrid.EditIndex].Cells[2].FindControl("txtSomeText")))).Text);
           // TODO:Save your Data
           gvMyGrid.EditIndex = -1;
           BindGridViewData();
        }
    }

So the promise is that they fixed the DataGrid by giving us the GridView... they've come a long way, and this is very workable for me.  If you can use the bound stuff then no code is needed, but if not (as was what seemed to be the case for me)... you can use this.


Published Feb 03 2006, 10:48 AM by Jay Kimble
Filed under: ,

Check out Devlicio.us!

This Blog

Syndication

News

CodeBetter.Com Home
Current Threat level
Terror Alert Level