1

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.

Sarah Vessels
  • 30,930
  • 33
  • 155
  • 222
  • _"I tried to refer to the buttons with variables based on the ID attribute in the markup"_ What does that mean? You've said that the visible property gets set correctly, so why _"btnView and btnEdit variables/properties don't exist"_? – Tim Schmelter May 21 '12 at 20:43
  • I can find the buttons via `FindControl`, and stepping through with the debugger I see that the values I'm setting the `Visible` property to look correct. However, no `btnView` or `btnEdit` variable exists in my MyPage.aspx.designer.cs auto-generated class, unlike for the `DetailsView`. This may be expected, I'm new to ASP.NET dev so I'm not sure what all variables get generated. – Sarah Vessels May 21 '12 at 20:48
  • 1
    That is normaly since only controls which `NamingContainer` is the page itself are initialized and accessible in the designer.cs-file. All others are initialized during the page-lifecycle. Anyway, that does not explain why your buttonsdon't change their visible state. Are you databinding the `DetailsView` on postbacks somewhere? That might be a reason. – Tim Schmelter May 21 '12 at 20:53
  • Hm, well I didn't have any mention of `IsPostBack` in my `Page_Load`, but adding `if (IsPostBack) { return; }` to the beginning of `Page_Load` didn't seem to help. – Sarah Vessels May 21 '12 at 20:57
  • That's a good idea anyway since it probably would be the next problem. I must admit that i'm not very familiar with DetailsView(unlike FormView) but i assume that you should use the [ModeChanged](http://msdn.microsoft.com/en-us/library/system.web.ui.webcontrols.detailsview.modechanged) event instead. [ModeChanging](http://msdn.microsoft.com/en-us/library/system.web.ui.webcontrols.detailsview.modechanging) is appropriate if you might want to cancel the change event. – Tim Schmelter May 21 '12 at 21:08

1 Answers1

2

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;
    }
}
Tim Schmelter
  • 450,073
  • 74
  • 686
  • 939