簡體   English   中英

什么時候確切地在ASP.NET的FormView中觸發OnItemUpdated事件?

[英]When exactly does the OnItemUpdated event fire specifically in a FormView in ASP.NET?

我無法確定OnItemUpdated何時被解雇。 我一直在搞怪ASP.NET,試圖學習它,所以您在這段代碼中看到的某些事情可能是有意地用困難的方式完成的(這樣我可以更好地了解幕后情況)

基本上,我有一個GridView,它是使用formview作為細節的主控件。

這是GridViewSelectedIndexChanged方法

protected void GridView1_SelectedIndexChanged(object sender, EventArgs e)
{
    var context = new DataAccessLayer.SafetyEntities();
    var se = (from c in context.Employees
                  where c.EID == (long)GridView1.SelectedDataKey.Value
                  select c).ToList();
    FormView1.DataSource = se;
    FormView1.DataKeyNames = new string[] { "EID" };
    FormView1.DataBind();
}

一切正常,它將在表格中顯示選定的詳細信息以進行編輯。 這是formview樣子:

<asp:FormView ID="FormView1" runat="server" DefaultMode="Edit" OnItemUpdating = "FormView1_ItemUpdating" OnItemUpdated="BLAH">
    <ItemTemplate>
        Select an employee!
     </ItemTemplate>
     <EditItemTemplate>
         <table>
             <tr>
                 <th>Name: 
                 </th>
                    <td>
                        <asp:TextBox runat="server" ID ="NameEdit" Text='<%#Bind("Name") %>' /> 
                    </td>
                    <br />
            </tr>
            <tr>
                <th>Manager: 
                </th>
                <td>
                    <asp:DropDownList ID = "DDLEdit1" DataSourceID = "ManagerEntitySource" runat="server"
                           DataTextField = "Option_Value" DataValueField = "Option_Value"
                           SelectedValue = '<%#Bind("Manager") %>'  
                           AppendDataBoundItems="true">
                    </asp:DropDownList> 
                </td>
                <br />
            </tr>
            <tr>
                <th>Location: 
                </th>
                <td>
                    <asp:DropDownList ID="DDLEdit2" DataSourceID = "LocationEntitySource" runat="server"
                           DataTextField = "Option_Value" DataValueField = "Option_Value"
                           SelectedValue='<%#Bind("Building") %>' 
                           AppendDataBoundItems="true">
                    </asp:DropDownList>
                </td>
                <br />
        </table>
        <asp:Button ID="Button2" Text="Submit Changes" runat="server" CommandName="Update" />
            <!--<asp:LinkButton ID = "LB1" Text="Update" CommandName="Update" runat="server" /> -->
    </EditItemTemplate>       
</asp:FormView>

這也可以。 您可以從FormView的屬性中看到我指定的OnItemUpdatingOnItemUpdated

這是OnItemUpdating

protected void FormView1_ItemUpdating(object source, FormViewUpdateEventArgs e)
{
   DebugBox.Text = FormView1.DataKey.Value.ToString();
   DataAccessLayer.SafetyEntities se = new DataAccessLayer.SafetyEntities();
   var key = Convert.ToInt32(FormView1.DataKey.Value.ToString());
   DataAccessLayer.Employee employeeToUpdate = se.Employees.Where(emp => emp.EID == key).First();
   employeeToUpdate.Name = e.NewValues["Name"].ToString();
   employeeToUpdate.Manager = e.NewValues["Manager"].ToString();
   employeeToUpdate.Building = e.NewValues["Building"].ToString();
   se.SaveChanges();
   GridView1.DataBind();

}

這也很好。 這些項目正在適當更新,並且GridView正在刷新。

這是OnItemUpdated

protected void BLAH(object source, FormViewUpdatedEventArgs e)
{
    DebugBox2.Text = "BLAH!!!!";
}

這就是問題所在。 這永遠不會被調用! 我是否在某個地方錯過了要觸發此事件的步驟? 我以為我知道該按鈕將調用Command =“ Update”,它將觸發ItemUpdating,然后觸發ItemUpdated。 它肯定調用ItemUpdating,但是僅此而已。 我還需要其他東西來激發ItemUpdated嗎?

結論:

查看FormView類的源代碼,似乎在使用DataBinding時未觸發ItemUpdated事件。

僅當您設置FormViewSelectMethodUpdateMethodDeleteMethodInsertMethod屬性時,才會觸發ItemUpdated事件。

證據

當您在FormView更新項目時,將調用其“ UpdateItem”方法,該方法在內部調用HandleUpdate

public virtual void UpdateItem(bool causesValidation)
    {
      this.ResetModelValidationGroup(causesValidation, string.Empty);
      this.HandleUpdate(string.Empty, causesValidation);
    }

private void HandleUpdate(string commandArg, bool causesValidation)
    {
       // Lots of work is done here
    }

HandleUpdate方法的底部,將觸發OnItemUpdating事件:

this.OnItemUpdating(e);

然后是一段相當奇怪的代碼行:

if (e.Cancel || !bindingAutomatic)
          return;

接下來依次調用dataSourceView上的Update

dataSourceView.Update((IDictionary) e.Keys, (IDictionary) e.NewValues, 
(IDictionary) e.OldValues, 
new DataSourceViewOperationCallback(this.HandleUpdateCallback));

我們可以看到Update方法的最后一個參數接受了一個回調,在這種情況下為HandleUpdateCallback HandleUpdateCallback是最終觸發OnItemUpdated事件的地方。

private bool HandleUpdateCallback(int affectedRows, Exception ex)
    {
      FormViewUpdatedEventArgs e1 = new FormViewUpdatedEventArgs(
                                                       affectedRows, ex);
      e1.SetOldValues(this._updateOldValues);
      e1.SetNewValues(this._updateNewValues);
      e1.SetKeys(this._updateKeys);
      this.OnItemUpdated(e1);
      // A lot of other stuff goes on here
     }

因此,這就是我們最終如何執行OnItemUpdated方法的映射,但是為什么在我們的案例中不執行該方法?

讓我們略過一下,但回到我前面提到的HandleUpdate方法的“好奇”部分:

if (e.Cancel || !bindingAutomatic)
          return;

這里發生了什么? 我們不是要取消事件,而是!bindingAutomatic ,那里發生了什么?

該值在HandleUpdate方法中進一步設置:

bool bindingAutomatic = this.IsDataBindingAutomatic;

IsDataBindingAutomatic這個屬性是BaseDataBound類(比FormView類更遠的基類)的內部屬性:

  protected internal bool IsDataBindingAutomatic
    {
      get
      {
        if (!this.IsBoundUsingDataSourceID)
          return this.IsUsingModelBinders;
        else
          return true;
      }
    }

由於我們沒有使用DataSourceID ,所以最終返回了IsUsingModelBinders的值。 這是BaseDataBoundControl上的一個虛擬屬性,在CompositeDataBoundControl類(我們的FormView直接繼承的基類)中重寫了該屬性。

現在,我們看一下直接確定是否將觸發OnItemUpdating方法的代碼:

protected override bool IsUsingModelBinders
    {
      get
      {
        if (string.IsNullOrEmpty(this.SelectMethod) 
            && string.IsNullOrEmpty(this.UpdateMethod) 
            && string.IsNullOrEmpty(this.DeleteMethod))
          return !string.IsNullOrEmpty(this.InsertMethod);
        else
          return true;
      }
    }

基本上是說,如果我們設置了SelectMethod,UpdateMethod或DeleteMethod(這些是FormView上的字符串屬性),則返回true,否則告訴我們是否設置了InsertMethod。 在我們的例子中,我們沒有設置任何這些屬性,因此返回的值為false

因為這是錯誤的,所以我們之前兩次的好奇代碼只是返回而從未到達觸發ItemUpdated事件的代碼部分。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM