![](/img/trans.png)
[英]ASP.NET/Webform Textbox does not fire the autopostback when onkeyup event defines “setTimeout” (IE9)
[英]When exactly does the OnItemUpdated event fire specifically in a FormView in ASP.NET?
我無法確定OnItemUpdated何時被解雇。 我一直在搞怪ASP.NET,試圖學習它,所以您在這段代碼中看到的某些事情可能是有意地用困難的方式完成的(這樣我可以更好地了解幕后情況)
基本上,我有一個GridView,它是使用formview作為細節的主控件。
這是GridView
的SelectedIndexChanged
方法
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
的屬性中看到我指定的OnItemUpdating
和OnItemUpdated
。
這是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
事件。
僅當您設置FormView
的SelectMethod
, UpdateMethod
, DeleteMethod
或InsertMethod
屬性時,才會觸發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.