我已經繼承了一些在Web部件控件中具有GridView和DetailsView的代碼。DetailsView:如何在新命令上使用CommandArgument設置HiddenField值?
DetailsView能夠創建兩種不同的對象,例如TypeA和TypeB。
有用於過濾由對象類型將GridView一個下拉列表和在DetailsView具有自動生成的插入按鈕。
<asp:DetailsView ID="myDetailsView"
AutoGenerateInsertButton="True"
AutoGenerateEditButton="True"
AutoGenerateRows="false"
OnItemUpdating="OnItemUpdating"
DefaultMode="ReadOnly"
OnDataBound="OnDetailsViewBound"
OnItemInserting="OnItemInserting"
OnModeChanging="OnDetailsViewModeChanging"
runat="server">
我一直在問:
- 刪除在GridView上的過濾器;和
- 將新按鈕/鏈接拆分爲兩個,因此有一個單獨的按鈕用於創建每種類型的對象。
刪除過濾器意味着我需要一些其他方式來跟蹤我們正在創建的對象類型。 我已經改變上述拆分的新鏈接:
<asp:DetailsView ID="myDetailsView"
AutoGenerateInsertButton="False"
AutoGenerateEditButton="True"
AutoGenerateRows="false"
OnItemUpdating="OnItemUpdating"
DefaultMode="ReadOnly"
OnDataBound="OnDetailsViewBound"
OnItemInserting="OnItemInserting"
OnModeChanging="OnDetailsViewModeChanging"
runat="server">
並添加
<FooterTemplate>
<asp:TemplateField>
<ItemTemplate>
<asp:LinkButton runat="server" ID="lnkCreateNewTypeA" CommandName="New" CommandArgument="TypeA" CssClass="buttonlink">New Type A</asp:LinkButton>
<asp:LinkButton runat="server" ID="lnkCreateNewTypeB" CommandName="New" CommandArgument="TypeB" CssClass="buttonlink">New Type B</asp:LinkButton>
</ItemTemplate>
</asp:TemplateField>
</FooterTemplate>
我還沒有刪除的過濾器,從而改變當前功能和以前一樣,因爲我使用新命令。 我希望能夠做的是以某種方式捕獲New事件,以便我可以將CommandArgument值置於隱藏字段中,然後DetailsView將使用它來確定它正在創建哪種類型的對象以及顯示/隱藏字段。 當我在代碼中的所有事件處理程序中放置斷點時,第一個斷點是OnDetailsViewModeChanging,它無法訪問CommandArgument。
當按下DetailsView中的任何按鈕時,觸發OnItemCommand(如果它已連接)並確實允許我訪問CommandArgument,但我不確定該方法需要做什麼以模仿事件鏈當您使用自動生成的按鈕時發生。
是我檢索CommandArgument捕捉到它在OnItemCommand事件處理程序,還是有被觸發的新命令的一些其他事件唯一的選擇?
任何人都可以向我解釋觸發新命令時發生的事件序列嗎?
我在某處閱讀它將模式更改爲「插入」,但我不知道它還有什麼作用。我相信OnItemInserting方法直到單擊「插入」鏈接纔會被調用。
任何幫助將感激地收到!
編輯:
我發現在DetailsView控件的事件此鏈接,但它並沒有回答我的問題。 http://msdn.microsoft.com/en-us/library/system.web.ui.webcontrols.detailsview_events.aspx
編輯:
我已經嘗試添加以下內容:
在ASCX:
<asp:DetailsView ID="myDetailsView"
...
OnItemCommand="OnItemCommand"
...
runat="server">
...
<asp:TemplateField HeaderText="Object Type" HeaderStyle-CssClass="columnHeader">
<ItemTemplate>
<asp:HiddenField runat="server" ID="hidObjectType" Value=""/>
<asp:Label runat="server" ID="lblObjectType"></asp:Label>
</ItemTemplate>
</asp:TemplateField>
在後面的代碼:
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;
}
}
}
我發現我不需要在此方法中設置模式(this.myDetailsView.ChangeMode(DetailsViewMode.Insert);
),因爲OnDetailsViewModeChanging事件處理程序仍然觸發。 這找到控件並正確設置它們的值。如果我在OnDetailsViewModeChanging再次檢查值,其值仍設置,但在這種方法的邏輯的一部分,還有就是
this.myDetailsView.DataBind()
通話導致回傳,在這一點上,值都將丟失。我試圖加入
EnableViewState="True"
但這沒有什麼區別。我已經回顧了頁面生命週期(http://spazzarama.files.wordpress.com/2009/02/aspnet_page-control-life-cycle.pdf),並認爲可能this.EnsureChildControls()
會有所幫助,但它也沒有區別。
另一種方法是將值存儲在會話中,但我寧願不要。