2012-11-07 37 views
1

我已經繼承了一些在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"> 

我一直在問:

  1. 刪除在GridView上的過濾器;和
  2. 將新按鈕/鏈接拆分爲兩個,因此有一個單獨的按鈕用於創建每種類型的對象。

刪除過濾器意味着我需要一些其他方式來跟蹤我們正在創建的對象類型。 我已經改變上述拆分的新鏈接:

<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()會有所幫助,但它也沒有區別。

另一種方法是將值存儲在會話中,但我寧願不要。

回答

0

據我所知,除了捕獲所有命令的OnItemCommand之外,沒有捕獲「新」命令的事件。 (注意:您需要確保在您的LinkBut​​ton上設置了CausesValidation="False",否則代碼不會破壞爲OnItemCommand)。

當單步調試代碼,出現以下情況:

  1. 後LinkBut​​ton的按下,OnItemCommand被觸發。 CommandName =「New」,這裏我可以檢索CommandArgument
  2. Next OnModeChanging被觸發。 e.NewMode =「插入」。從我所看到的所有的例子,在這裏你撥打ChangeMode在DetailsView控件,然後就可以調用DataBind()
  3. 下一頁OnDataBound被觸發作爲調用數據綁定的結果()

我沒有找到一個在各種事件之間保留隱藏變量的值的方法,所以我最終使用了一個會話變量。代碼如下,以防萬一任何人想要它。

DetailsView控件聲明中ASCX:

<asp:DetailsView ID="myDetailsView" 
     AutoGenerateInsertButton="False" 
     AutoGenerateEditButton="True" 
     AutoGenerateRows="false" 
     OnItemInserting="OnItemInserting" 
     OnItemUpdating="OnItemUpdating" 
     OnItemCommand="OnItemCommand" 
     DefaultMode="ReadOnly" 
     OnDataBound="OnDetailsViewBound" 
     OnModeChanging="OnDetailsViewModeChanging"   
     runat="server"> 

在後臺代碼:

常量聲明...

private const string SESSIONKEY_MYVALUE = "MyValue"; 
    private const string DEFAULT_OBJECTTYPE = "TypeA"; 

OnItemCommand事件處理程序...

protected void OnItemCommand(object sender, DetailsViewCommandEventArgs e) 
    { 
     if (e.CommandName.Equals("New", StringComparison.InvariantCultureIgnoreCase)) 
     { 
      var objectType = e.CommandArgument.ToString(); 

      HiddenField typeHidden = this.myDetailsView.FindControl("hidObjectType") as HiddenField; 
      if (typeHidden != null) 
      { 
       typeHidden.Value = objectType; 
      } 

      HttpContext.Current.Session[SESSIONKEY_MYVALUE] = objectType; 
     } 
    } 

OnModeChanging事件處理程序....

protected void OnDetailsViewModeChanging(Object sender, DetailsViewModeEventArgs e) 
    { 
     if (e.NewMode == DetailsViewMode.Insert) 
     { 
      this.myDetailsView.ChangeMode(DetailsViewMode.Insert); 
      this.myDetailsView.DataBind(); 
     } 
    } 

OnDataBound事件處理程序...

protected void OnDetailsViewBound(object sender, EventArgs e) 
    { 
     if (this.myDetailsView.CurrentMode == DetailsViewMode.Insert) 
     { 
      var sessionVar = HttpContext.Current.Session[SESSIONKEY_MYVALUE]; 
      var objectType = sessionVar == null ? 
       DEFAULT_OBJECTTYPE : 
       sessionVar.ToString(); 

      var typeHidden = this.myDetailsView.FindControl("hidObjectType") as HiddenField; 

      if (typeHidden != null) 
      { 
       typeHidden.Value = objectType; 
      } 
     } 
    } 
相關問題