1
votes

I have some issue with ASP.net Gridview that I hope people here can help me.

Requirements

  • Gridview whole row to be clickable to open another page
  • In editing mode, can change table values through edititemtemplate textbox

Problem

Textbox selection causes the entire row click event to fire and prevents user from changing the textbox text. User can edit table value without opening different page.

ASP Page

<asp:GridView ID="remarksGV1" runat="server" AllowPaging="true" DataKeyNames="REM_ID"
            OnRowDataBound="remarksGV1_RowDataBound" OnSelectedIndexChanged="remarksGV1_SelectedIndexChanged"
            OnRowEditing="remarksGV1_RowEditing"
            OnRowCancelingEdit="remarksGV1_RowCancelingEdit"
            OnRowUpdating="remarksGV1_RowUpdating"
            AutoPostBack="false"
            HeaderStyle-CssClass="thead-dark"
            CssClass="table table-striped thead-dark table-borderless table-hover border-0 hand"
            AutoGenerateColumns="false">
            <Columns>
                <asp:TemplateField HeaderText="No.">
                    <ItemTemplate>
                        <%# Container.DataItemIndex + 1 %>
                    </ItemTemplate>
                </asp:TemplateField>
                <asp:TemplateField HeaderText="Title">
                    <ItemTemplate>
                        <asp:Label ID="titleLbl" runat="server" Text='<%# Bind("REM_TITLE") %>' />
                    </ItemTemplate>
                    <EditItemTemplate>
                        <asp:TextBox ID="titleTB" runat="server" />
                    </EditItemTemplate>
                </asp:TemplateField>
                <asp:BoundField DataField="REM_DESC" HeaderText="Remarks Description" ReadOnly="true" />
                <asp:BoundField DataField="CREATE_DATE" DataFormatString="{0:d}" HeaderText="Date Created" ReadOnly="true" />
                <asp:BoundField DataField="UPD_DATE" DataFormatString="{0:d}" HeaderText="Last Updated" ReadOnly="true" />
                <asp:TemplateField>
                    <ItemTemplate>
                        <asp:Button Text="Edit" ID="EditBtn" CssClass="btn-action" runat="server" CommandName="Edit" />
                    </ItemTemplate>
                    <EditItemTemplate>
                        <asp:Button Text="Update" ID="UpdateBtn" CssClass="btn-action" runat="server" CommandName="Update" />
                        <asp:Button Text="Cancel" ID="CancelBtn" CssClass="btn-action" runat="server" CommandName="Cancel" />
                    </EditItemTemplate>
                </asp:TemplateField>
            </Columns>
        </asp:GridView>

Code behind

private void BindGrid()
    {
        Debug.WriteLine("BindGrid called");

        int proj_code = Int32.Parse(ViewState["proj_cd"].ToString());

        ProjectRepository remarksRepository = new ProjectRepository();
        var remarks = remarksRepository.GetRemarks(proj_code, proj_task_code, proj_stask1_cd, proj_stask2_cd);
        remarksGV1.DataSource = remarks;
        remarksGV1.DataBind();
    }

    protected void Unnamed_Click(object sender, EventArgs e)
    {
        Launch.PageEvent(this, (LinkButton)sender, ViewState["proj_cd"].ToString());
    }

    protected void remarksGV1_RowDataBound(object sender, GridViewRowEventArgs e)
    {
        try
        {
            switch (e.Row.RowType)
            {
                case DataControlRowType.Header:
                    //...
                    break;
                case DataControlRowType.DataRow:
                    e.Row.Attributes.Add("onclick", Page.ClientScript.GetPostBackEventReference(remarksGV1, "Select$" + e.Row.RowIndex.ToString()));
                    break;
            }
        }
        catch
        {
            //...throw
        }

        if (e.Row.RowType == DataControlRowType.DataRow)
        {
            TextBox titleTB = (e.Row.FindControl("titleTB") as TextBox);

            int prj_cd = Int32.Parse(ViewState["proj_cd"].ToString());
            ProjectRepository repository = new ProjectRepository();
            var remarks = repository.GetRemarks(prj_cd, proj_task_code, proj_stask1_cd, proj_stask2_cd);
            Debug.WriteLine("Remarks Count: " + remarks.Count);
            TMS_PROJ_REMARK remark = remarks.First(x => x.REM_ID == Convert.ToInt64(DataBinder.Eval(e.Row.DataItem, "REM_ID")));

            if (titleTB != null)
            {
                titleTB.Text = remark.REM_TITLE;
            }
        }
    }

    protected void remarksGV1_SelectedIndexChanged(object sender, EventArgs e)
    {
        int row = remarksGV1.SelectedIndex;
        long rem_id = (long)remarksGV1.DataKeys[row]["REM_ID"];
        Debug.WriteLine("REM ID: " + rem_id);

        Session["edit_remarks"] = true;
        Dictionary<string, string> pairs = new Dictionary<string, string>();
        pairs["rem_id"] = rem_id.ToString();
        pairs["proj_cd"] = ViewState["proj_cd"].ToString();
        Launch.ToPage(this, "Project_Remarks_In_2.aspx", pairs);
    }

    protected void btnAddRemarks_Click(object sender, EventArgs e)
    {
        Session["new_remarks"] = true;
        Dictionary<string, string> pairs = new Dictionary<string, string>();
        pairs["proj_cd"] = ViewState["proj_cd"].ToString();

        string url = "Project_Remarks_In_1.aspx";

        Launch.ToPage(this, url, pairs);
    }

    private void SetTitle()
    {
        ProjectRepository repository = new ProjectRepository();
        TMS_PROJ_MASTER project = repository.GetProject(Convert.ToInt32(ViewState["proj_cd"]));
        this.Title = "Remarks - " + project.PROJ_TITLE;
    }

    protected void remarksGV1_RowEditing(object sender, GridViewEditEventArgs e)
    {
        remarksGV1.EditIndex = e.NewEditIndex;
        BindGrid();
    }

    protected void remarksGV1_RowUpdating(object sender, GridViewUpdateEventArgs e)
    {
        // Do stuff
        ProjectRepository repository = new ProjectRepository();
        GridViewRow row = remarksGV1.Rows[e.RowIndex];
        TextBox titleTB = (row.FindControl("titleTB") as TextBox);

        long rem_id = Convert.ToInt64(remarksGV1.DataKeys[e.RowIndex].Value);
        var db = new THPEntities();
        TMS_PROJ_REMARK remark = db.TMS_PROJ_REMARK
            .First(x => x.REM_ID == rem_id);
        remark.REM_TITLE = titleTB.Text;
        remark.UPD_DATE = DateTime.Now;
        db.SaveChanges();

        // Bind Grid
        remarksGV1.EditIndex = -1;
        BindGrid();
    }

    protected void remarksGV1_RowCancelingEdit(object sender, GridViewCancelEditEventArgs e)
    {
        remarksGV1.EditIndex = -1;
        BindGrid();
    }
1

1 Answers

3
votes

I suggest in this part of your code, do not add the full line click when you edit the line (I have add one -if- to check for the edit).

 switch (e.Row.RowType)
            {
                case DataControlRowType.Header:
                    //...
                    break;
                case DataControlRowType.DataRow:
                    if((e.Row.RowState & DataControlRowState.Edit) != DataControlRowState.Edit)
                           e.Row.Attributes.Add("onclick", Page.ClientScript.GetPostBackEventReference(remarksGV1, "Select$" + e.Row.RowIndex.ToString()));
                    break;
            }