Sma*_*ode 1 .net c# asp.net webforms event-handling
当OnItemUpdated被解雇时,我不能为我的生活找到答案.我一直在使用ASP.NET来试图学习它,所以你在这段代码中看到的一些东西可能是故意做的(所以我可以更好地理解幕后发生的事情)
基本上,我有一个GridView,它是使用formview作为细节的主控件.
这是SelectedIndexChanged方法GridView
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();
}
Run Code Online (Sandbox Code Playgroud)
这样工作正常,它会在表单中显示所选的详细信息以进行编辑.这是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>
Run Code Online (Sandbox Code Playgroud)
这也有效.您可以从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();
}
Run Code Online (Sandbox Code Playgroud)
这也很好.这些项目正在适当更新,GridView令人耳目一新.
这是OnItemUpdated:
protected void BLAH(object source, FormViewUpdatedEventArgs e)
{
DebugBox2.Text = "BLAH!!!!";
}
Run Code Online (Sandbox Code Playgroud)
这就是问题所在.永远不会被称为!我错过了某个地方让这个事件发生了吗?我以为我理解按钮会调用Command ="Update",它会触发ItemUpdating,然后触发ItemUpdated.它肯定称为ItemUpdating,但就是这样.我需要额外的东西来解雇ItemUpdated吗?
结论:
查看FormView类的源代码,似乎ItemUpdated在使用DataBinding时不会触发事件.
该ItemUpdated事件仅当您设置被炒鱿鱼SelectMethod,UpdateMethod,DeleteMethod或InsertMethod的性质FormView.
证据
当您更新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
}
Run Code Online (Sandbox Code Playgroud)
在HandleUpdate方法的底部,OnItemUpdating触发事件:
this.OnItemUpdating(e);
Run Code Online (Sandbox Code Playgroud)
然后是一段相当奇怪的代码:
if (e.Cancel || !bindingAutomatic)
return;
Run Code Online (Sandbox Code Playgroud)
这又是通过调用followd来Update的dataSourceView.
dataSourceView.Update((IDictionary) e.Keys, (IDictionary) e.NewValues,
(IDictionary) e.OldValues,
new DataSourceViewOperationCallback(this.HandleUpdateCallback));
Run Code Online (Sandbox Code Playgroud)
我们可以看到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
}
Run Code Online (Sandbox Code Playgroud)
那么,这就是我们最终如何获得OnItemUpdated正在执行的方法的映射,但为什么不在我们的情况下执行呢?
让我们稍微回过头来看一下HandleUpdate前面提到的方法的"好奇"部分:
if (e.Cancel || !bindingAutomatic)
return;
Run Code Online (Sandbox Code Playgroud)
这里发生了什么?我们不会取消我们的活动,但那里!bindingAutomatic发生了什么?
该值在HandleUpdate方法中进一步设置:
bool bindingAutomatic = this.IsDataBindingAutomatic;
这个属性IsDataBindingAutomatic是类的内部属性BaseDataBound(从我们的FormView类开始的一个基类进一步向上):
protected internal bool IsDataBindingAutomatic
{
get
{
if (!this.IsBoundUsingDataSourceID)
return this.IsUsingModelBinders;
else
return true;
}
}
Run Code Online (Sandbox Code Playgroud)
由于我们没有使用,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;
}
}
Run Code Online (Sandbox Code Playgroud)
这基本上说如果我们设置了SelectMethod,UpdateMethod或DeleteMethod(这些是FormView上的字符串属性),则返回true,否则告诉我们是否设置了InsertMethod.在我们的例子中,我们没有设置任何这些属性,因此我们获得了返回值false.
因为这是错误的,我们早期两次的好奇代码只返回并且永远不会到达触发ItemUpdated事件的代码部分.
| 归档时间: |
|
| 查看次数: |
1887 次 |
| 最近记录: |