ASP.NET - button visibility change in DetailsView HeaderTemplate not working in OnModeChanging handler

4.1k views Asked by At

I have this markup:

<asp:DetailsView ID="dvDatabase" OnModeChanging="dvDatabase_ModeChanging">
    <HeaderTemplate>
        <asp:Button ID="btnView" runat="server" CausesValidation="False" CommandName="Cancel"
            Text="View" CssClass="btn btn-primary" Visible="false" />
        <asp:Button runat="server" CausesValidation="False" CommandName="Edit"
            Text="Edit" CssClass="btn btn-success" ID="btnEdit" />
        <asp:Button runat="server" CausesValidation="False" CommandName="Delete"
            Text="Delete" CssClass="btn btn-danger" />
    </HeaderTemplate>
    ...

Then I have this C#:

protected void dvDatabase_ModeChanging(object sender, DetailsViewModeEventArgs e)
{
    bool isEdit = DetailsViewMode.Edit == e.NewMode;
    DetailsView view = (DetailsView)sender;
    Button viewButton = (Button)view.FindControl("btnView");
    Button editButton = (Button)view.FindControl("btnEdit");
    viewButton.Visible = isEdit;
    editButton.Visible = !isEdit;
}

I've done some debugging and the Visible property gets set correctly, but I never see the buttons change. I hit the Edit button and I'm in edit mode, but the Edit button is still displayed and the View button is still hidden. I've tried finding the buttons via dvDatabase.FindControl directly, rather than using the object sender variable, but that doesn't work either. I tried to refer to the buttons with variables based on the ID attribute in the markup, but btnView and btnEdit variables/properties don't exist. What's going on?

Edit: I switched to OnModeChanged as per Tim's suggestion, but the buttons still don't change. Here's my C# now:

protected void dvDatabase_ModeChanged(object sender, EventArgs e)
{
    DetailsView view = /*(DetailsView)sender*/dvDatabase;
    bool isEdit = DetailsViewMode.Edit == view.CurrentMode;
    LinkButton viewButton = (LinkButton)view.FindControl("btnView");
    LinkButton editButton = (LinkButton)view.FindControl("btnEdit");
    viewButton.Visible = isEdit;
    editButton.Visible = !isEdit;
}

I tried using the object sender as well as the dvDatabase class variable, but neither seemed to have an effect.

1

There are 1 answers

0
Tim Schmelter On BEST ANSWER

Use the DetailsView's DataBound event instead and only databind the DetailsView if(!Page.IsPostback). You also need to handle the ItemCommand event to call the appropriate ChangeMode method and databind the DetailsView.

protected void dvDatabase_DataBound(Object sender, EventArgs e)
{ 
    var view = (DetailsView)sender;
    var btnView = (Button)view.FindControl("btnView");
    var btnEdit = (Button)view.FindControl("btnEdit");
    switch (view.CurrentMode)
    { 
        case DetailsViewMode.ReadOnly:
            btnView.Visible = false;
            btnEdit.Visible = true;
            break;
        case DetailsViewMode.Edit:
            btnView.Visible = true;
            btnEdit.Visible = false;
            break;
        case DetailsViewMode.Insert:
            btnView.Visible = false;
            btnEdit.Visible = false;
            break;
        default:
            break;
    }
}