Industrial Themes
Industrial Themes

Reputation: 567

How do I programmatically create a button inside a DetailsView and give it a CommandName?

Within a DetailsView I am creating a delete button programmatically and giving it a CommandName. The button gets created fine when I test my app, but when I click the delete button, nothing happens. If I create this exact same button with the same CommandName regularly in the DetailsView, it works perfectly and fires the ItemCommand of the DetailsView correctly. That means there is something wrong with the way I'm creating my button in the code, but I can't figure out what it is. Do I need to specify a UniqueID or something like that?

Here is my code that programmatically creates the delete button, which doesn't work:

Public Sub GetAttachments(ByVal requestID As Integer)
    Try
        Dim pnlAttachments As Panel = dtlApplication.FindControl("pnlAttachments")
        Dim btnDelete As New LinkButton
        btnDelete.Text = "delete"
        btnDelete.CssClass = "lblDeleteAttachment"
        btnDelete.CommandName = "DeleteAttachment"
        btnDelete.ID = "lnkDeleteAttachment"
        pnlAttachments.Controls.Add(btnDelete)
    Catch ex As Exception
        'notify user on screen
        lblGeneralError.Text = ex.ToString
        lblGeneralError.CssClass = "red"
    End Try
End Sub  

And if I create the button regularly like this, it works fine:

<asp:LinkButton runat="server" ID="lnkDeleteAttachment" Text="delete" commandname="DeleteAttachment" CssClass="lblDeleteAttachment"></asp:LinkButton>

Here is the rendered page output for the programmatically created button that doesn't work:

<a id="MainContent_dtlApplication_lnkDeleteAttachment" href="javascript:__doPostBack('ctl00$MainContent$dtlApplication$lnkDeleteAttachment','')">delete</a>

And here is the rendered page output for the regularly created button that works:

<a id="MainContent_dtlApplication_lnkDeleteAttachment" href="javascript:__doPostBack('ctl00$MainContent$dtlApplication$lnkDeleteAttachment','')">delete</a>

You can see they are identical.

Note: The reason I'm creating it programmatically is because eventually I'm going to add several delete buttons inside a For Next statement, and at this point I won't have a choice of whether or not to create it regularly or programmatically.

Upvotes: 0

Views: 1173

Answers (3)

Win
Win

Reputation: 62260

Please refer to the code. I can catch the button command in button1_Command. However, you need to attach the event handler - button1.Command += button1_Command;

<asp:DetailsView ID="DetailsView1" runat="server" Height="50px" Width="125px" OnItemCommand="DetailsView1_ItemCommand"
    OnDataBound="DetailsView1_DataBound" AllowPaging="true">
    <Fields>
        <asp:TemplateField>
            <ItemTemplate>
                <asp:Panel ID="Panel1" runat="server">
                </asp:Panel>
            </ItemTemplate>
        </asp:TemplateField>
    </Fields>
</asp:DetailsView>

public class Customer
{
    public int CustomerId { get; set; }
    public string FirstName { get; set; }
    public string LastName { get; set; }
}

private List<Customer> _customers;

public List<Customer> Customers
{
    get
    {
        if (_customers == null)
        {
            _customers = new List<Customer>();

            _customers.Add(new Customer {CustomerId = 1, FirstName = "Jon", LastName = "Doe"});
            _customers.Add(new Customer {CustomerId = 2, FirstName = "Mary", LastName = "Doe"});
            _customers.Add(new Customer {CustomerId = 3, FirstName = "Brian", LastName = "Newton"});
        }
        return _customers;
    }
}

protected void Page_Load(object sender, EventArgs e)
{
    DetailsView1.DataSource = Customers;
    DetailsView1.DataBind();
}

protected void DetailsView1_DataBound(object sender, EventArgs e)
{
    Panel panel1 = DetailsView1.FindControl("Panel1") as Panel;
    Button button1 = new Button();
    button1.Text = "Delete";
    button1.Command += button1_Command;
    button1.CommandName = "Delete";
    panel1.Controls.Add(button1);
}

void button1_Command(object sender, CommandEventArgs e)
{
    // Delete data here
}

Upvotes: 0

Icarus
Icarus

Reputation: 63966

You need to add the onclick event handler on every postback if you want it to fire. My suggestion is that you let it declared in your markup with a visible property to false and just make it visible when you need it to be visible. You won't have to deal with this kind of thing and the control will not be rendered anyway unless is set to visible at some point.

Upvotes: 1

Steve Wellens
Steve Wellens

Reputation: 20620

It might me easier to create the button in markup and then hide or show it programmatically.

Upvotes: 0

Related Questions