Note that there are some explanatory texts on larger screens.

plurals
  1. PODetailsView: How to set a HiddenField value using the CommandArgument on a New command?
    text
    copied!<p>I have inherited some code that has a GridView and a DetailsView in a webpart control. </p> <p>The DetailsView is able to create two different kinds of an object e.g. TypeA and TypeB. </p> <p>There's a dropdown list that filters the GridView by object type and the DetailsView has an automatically generated Insert button. </p> <pre><code>&lt;asp:DetailsView ID="myDetailsView" AutoGenerateInsertButton="True" AutoGenerateEditButton="True" AutoGenerateRows="false" OnItemUpdating="OnItemUpdating" DefaultMode="ReadOnly" OnDataBound="OnDetailsViewBound" OnItemInserting="OnItemInserting" OnModeChanging="OnDetailsViewModeChanging" runat="server"&gt; </code></pre> <p>I have been asked to:</p> <ol> <li>remove the filter on the GridView; and</li> <li>split the New buttons/links into two so there's a separate button for creating each type of object. </li> </ol> <p>Removing the filter means that I need some other way to track what kind of object we're creating. I have split the New links by changing the above to:</p> <pre><code>&lt;asp:DetailsView ID="myDetailsView" AutoGenerateInsertButton="False" AutoGenerateEditButton="True" AutoGenerateRows="false" OnItemUpdating="OnItemUpdating" DefaultMode="ReadOnly" OnDataBound="OnDetailsViewBound" OnItemInserting="OnItemInserting" OnModeChanging="OnDetailsViewModeChanging" runat="server"&gt; </code></pre> <p>and adding</p> <pre><code> &lt;FooterTemplate&gt; &lt;asp:TemplateField&gt; &lt;ItemTemplate&gt; &lt;asp:LinkButton runat="server" ID="lnkCreateNewTypeA" CommandName="New" CommandArgument="TypeA" CssClass="buttonlink"&gt;New Type A&lt;/asp:LinkButton&gt; &lt;asp:LinkButton runat="server" ID="lnkCreateNewTypeB" CommandName="New" CommandArgument="TypeB" CssClass="buttonlink"&gt;New Type B&lt;/asp:LinkButton&gt; &lt;/ItemTemplate&gt; &lt;/asp:TemplateField&gt; &lt;/FooterTemplate&gt; </code></pre> <p>I haven't yet removed the filter so the changes currently function the same as before, as I'm using the New command. What I was hoping to be able to do is somehow capture the New event so I can put the CommandArgument value into a hidden field, that the DetailsView would then use to determine which type of object it's creating and also to show/hide fields. When I put breakpoints in all of the event handlers in my code, the first one to break is OnDetailsViewModeChanging, which doesn't have access to the CommandArgument. </p> <p>OnItemCommand (if it's hooked up) is triggered when any button within the DetailsView is pressed and does give me access to the CommandArgument but I'm not sure what exactly needs to be done within this method to mimic the chain of events that occurs when you use automatically generated buttons. </p> <p>Is my only option for retrieving the CommandArgument to capture it in the OnItemCommand event handler or is there some other event that is triggered on the New command?</p> <p>Can anyone explain to me the sequence of events that occurs when the New command is triggered? </p> <p>I read somewhere that it changes the mode to Insert but I don't know what else it does. I believe the OnItemInserting method isn't called until the "Insert" link is clicked. </p> <p>Any help would be gratefully received!!</p> <hr> <p><strong>Edit:</strong></p> <p>I have found this link on DetailsView events but it hasn't answered my question. <a href="http://msdn.microsoft.com/en-us/library/system.web.ui.webcontrols.detailsview_events.aspx" rel="nofollow">http://msdn.microsoft.com/en-us/library/system.web.ui.webcontrols.detailsview_events.aspx</a></p> <hr> <p><strong>Edit:</strong></p> <p>I have tried adding the following:</p> <p>in ascx:</p> <pre><code>&lt;asp:DetailsView ID="myDetailsView" ... OnItemCommand="OnItemCommand" ... runat="server"&gt; ... &lt;asp:TemplateField HeaderText="Object Type" HeaderStyle-CssClass="columnHeader"&gt; &lt;ItemTemplate&gt; &lt;asp:HiddenField runat="server" ID="hidObjectType" Value=""/&gt; &lt;asp:Label runat="server" ID="lblObjectType"&gt;&lt;/asp:Label&gt; &lt;/ItemTemplate&gt; &lt;/asp:TemplateField&gt; </code></pre> <p>in code behind:</p> <pre><code>protected void OnItemCommand(object sender, DetailsViewCommandEventArgs e) { if (e.CommandName.Equals("New")) { var objectType = e.CommandArgument.ToString(); HiddenField typeHidden = this.myDetailsView.FindControl("hidObjectType") as HiddenField; if (typeHidden != null) { typeHidden.Value = objectType; } Label typeLabel = this.myDetailsView.FindControl("lblObjectType") as Label; if (typeLabel != null) { typeLabel.Text = objectType; } } } </code></pre> <p>I found that I didn't need to set the mode (<code>this.myDetailsView.ChangeMode(DetailsViewMode.Insert);</code>) in this method, as the OnDetailsViewModeChanging event handler still triggered. This finds the controls and sets the values on them correctly. If I check the values again in OnDetailsViewModeChanging, their values are still set but as part of the logic in this method, there is a call to </p> <pre><code>this.myDetailsView.DataBind() </code></pre> <p>which causes a postback and at this point, the values are lost. I tried adding</p> <pre><code>EnableViewState="True" </code></pre> <p>but this made no difference. I've reviewed the page lifecycle (http://spazzarama.files.wordpress.com/2009/02/aspnet_page-control-life-cycle.pdf) and thought that maybe <code>this.EnsureChildControls()</code> would help but it's also made no difference.</p> <p>An alternative would be to store the value in the session but I'd rather not.</p>
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload