Melanie
Melanie

Reputation: 3111

Programmatically add New button to ASP.Net DetailsView

I have an ASP.Net 4.5.1 web application that has a page with a GridView and a DetailsView. The two controls are linked, so that when a Select button is clicked in the GridView, the DetailsView displays the data for that row. The DetailsView record has an Edit and a Delete button. This all works fine. However, I don't want to add a New button at the bottom of the DetailsView along with the Edit and Delete buttons. I don't see any reason why my user should have to select an existing record before entering a new record into the dataset.

So - I've created an ASP button at the top of the page called btnNew. What this button is supposed to do is open the DetailsView and change its mode to Insert. I have two buttons in the DetailsView FooterTemplate, btnInsert and btnCancel. They are not visible by default, but I make them visible when btnNew is clicked.

Here's the problem: when I click on btnNew the first time, the DetailsView opens in Insert mode and btnInsert and btnCancel display properly. HOWEVER, if I click on btnCancel (the DetailsView and two buttons disappear, all good) and then click on btnNew again, the DetailsView appears, but btnInsert and btnCancel don't. If I click btnNew a second time, they show up. If I move the line in btnNew_Click (see below) that changes the DetailsView mode to Insert to the bottom of the method, then when I click on btnNew the first time, I don't see btnInsert and btnCancel, but when I click on it a second time, they show up. When I walk through the code in Debug mode, btnInsert and btnCancel are found, and their Visible property is set to True, but they aren't displayed.

I've simplified my code down to a page with just a DetailsView (no GridView) with no databinding, with no Master Page, with no Ajax controls, but the problem behavior persists. Below is this simplified code. First my markup:

<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="SimpleDefault.aspx.cs" Inherits="ElectronicCaseFilingHistory.SimpleDefault" %>

<!DOCTYPE html>

<html xmlns="http://www.w3.org/1999/xhtml">
<head id="Head1" runat="server">
    <title></title>
</head>
<body>
    <form id="form1" runat="server">
    <div>
    <asp:Button runat="server" ID="btnNew" Text="Add New" OnClick="btnNew_Click" BackColor="#F8F8F8" BorderColor="#9BE8E8" ForeColor="#3C3C3C" />
    <asp:DetailsView runat="server" ID="dvFilingDetail" AutoGenerateRows="false" >
        <Fields>
            <asp:TemplateField HeaderText="Attorney" HeaderStyle-Font-Bold="true">
                <ItemTemplate>
                    <asp:Label runat="server" ID="lbAttorneyName" />
                </ItemTemplate>
                <EditItemTemplate>
                    <asp:TextBox runat="server" ID="tbAttorneyName" />
                </EditItemTemplate>
            </asp:TemplateField>
            <asp:TemplateField HeaderText="Court" HeaderStyle-Font-Bold="true">
                <ItemTemplate>
                    <asp:Label runat="server" ID="lbCourt" />
                </ItemTemplate>
                <EditItemTemplate>
                    <asp:TextBox runat="server" ID="tbCourt" />
                </EditItemTemplate>
            </asp:TemplateField>
        </Fields>
        <FooterTemplate>
            <asp:Button runat="server" ID="btnInsert" Visible="false" Text="Insert" />
            <asp:Button runat="server" ID="btnCancel" Visible="false" OnClick="btnCancel_Click" Text="Cancel" />
        </FooterTemplate>
    </asp:DetailsView>
    </div></form></body></html>

Now the code behind:

using System;
using System.Collections.Generic;
using System.Data;
using System.Data.SqlClient;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;

namespace ElectronicCaseFilingHistory
{

public partial class SimpleDefault : System.Web.UI.Page
{

    protected void Page_Load(object sender, EventArgs e)
    {

    }

    protected void btnNew_Click(object sender, EventArgs e)
    {
        dvFilingDetail.ChangeMode(DetailsViewMode.Insert);  
        Button insert = (Button)dvFilingDetail.FindControl("btnInsert");
        Button cancel = (Button)dvFilingDetail.FindControl("btnCancel");
        if (insert != null)
            insert.Visible = true;
        if (cancel != null)
            cancel.Visible = true;  
    }

    protected void btnCancel_Click(object sender, EventArgs e)
    {
        dvFilingDetail.ChangeMode(DetailsViewMode.ReadOnly);
        dvFilingDetail.DataBind();
    }
}
}

I've tried adding an InsertItemTemplate in addition to an EditItemTemplate, but that has no effect. I also added CommandName=New to btnNew and added an ItemCommand event to the DetailsView to try to do it that way, but the ItemCommand method was never hit.

What am I doing wrong?

Upvotes: 1

Views: 1619

Answers (1)

samvdst
samvdst

Reputation: 638

After changing DetailsViewMode to Insert you have to call DataBind(); as well.

protected void btnNew_Click(object sender, EventArgs e)
{
    dvFilingDetail.ChangeMode(DetailsViewMode.Insert);
    dvFilingDetail.DataBind();

    Button insert = (Button)dvFilingDetail.FindControl("btnInsert");
    Button cancel = (Button)dvFilingDetail.FindControl("btnCancel");
    if (insert != null)
    {
        insert.Visible = true;
    }
    if (cancel != null)
    {
        cancel.Visible = true;
    }
}

Upvotes: 1

Related Questions