C# 事件处理程序中WebForms控件上的属性集在事件处理程序返回后恢复
我正在更新自定义事件处理程序中WebForms控件的属性,但当控件从事件处理程序返回时,该属性将恢复到原来的状态 以下是代码背后的相关部分:C# 事件处理程序中WebForms控件上的属性集在事件处理程序返回后恢复,c#,asp.net,events,C#,Asp.net,Events,我正在更新自定义事件处理程序中WebForms控件的属性,但当控件从事件处理程序返回时,该属性将恢复到原来的状态 以下是代码背后的相关部分: public partial class EditorLayoutv4 : System.Web.UI.Page { protected void Page_Load(object oSender, EventArgs oEventArgs) { if (!IsPostBack) { moSelect
public partial class EditorLayoutv4 : System.Web.UI.Page
{
protected void Page_Load(object oSender, EventArgs oEventArgs)
{
if (!IsPostBack) {
moSelectedContentBlock.NeedsCommitChanged += ContentBlock_NeedsCommitChanged;
}
else {
// restore fields from Page.Session[]
}
}
protected void Page_Prerender(object sender, EventArgs e) {
// save fields to Page.Session[]
}
private void RefreshContentBlockInfoButtons()
{
btnSaveContentBlockChanges.Enabled = moSelectedContentBlock.NeedsCommit; // breakpoint location A
btnDiscardContentBlockChanges.Enabled = moSelectedContentBlock.NeedsCommit;
}
protected void ContentBlock_NeedsCommitChanged(object oSender, EventArgs oEventArgs)
{
myContentBlockRow oContentBlock = (myContentBlockRow)oSender;
if (oContentBlock.Enabled)
{
if (oContentBlock == moSelectedContentBlock)
{
RefreshContentBlockInfoButtons();
}
}
}
protected void txtContentBlockName_TextChanged(object oSender, EventArgs oEventArgs)
{
moSelectedContentBlock.Name = txtContentBlockName.Text; // breakpoint location B
}
}
public sealed class ContentBlock {
public string Name {
get { return GetNameFromDB(); }
set {
if (value != GetNameFromDB()) {
PutNameInDB(value);
OnNeedsCommitChanged();
}
}
private void OnNeedsCommitChanged()
{
RowStateChangeHandler hHandler = this.NeedsCommitChanged;
if (hHandler != null)
{
hHandler(this, EventArgs.Empty);
}
}
public event EventHandler NeedsCommitChanged;
}
执行过程如下:当用户更改控件的值(在本例中为txtContentBlockName
)时,它会触发相应的事件(在本例中为TextChanged
),并将控件传递给代码后面的相应处理程序(在本例中为txtContentBlockName\u TextChanged()
)。在ContentBlock
对象中,当我设置一个属性(在本例中是Name
)时,setter会验证它实际上是一个更改,然后触发一个NeedsCommitChanged
事件,该事件是在类中定义的,该页面对象使用ContentBlock\u NeedsCommitChanged
作为处理程序订阅的。处理程序(除其他外)根据数据是否需要提交到数据库来更新保存和放弃按钮的状态。到目前为止,一切正常
这里的问题是:按钮的启用状态更改在ContentBlock\u NeedsCommitChanged()
返回和控件传回txtContentBlockName\u TextChanged()
之间的某个时间点恢复为false。我如上所示设置断点,然后在断点位置B单步执行,在离开TextChanged处理程序的控制之前在位置A中断。我在按钮控件上放了一块手表,看到Enabled属性设置为true。我保持单步执行——控制传递回ContentBlock\u NeedsCommitChanged()
,并且Enabled属性仍然为true。另一个步骤将我带到ContentBlock.OnNeedsCommitChanged()
,然后是ContentBlock.Name
setter,正如我所期望的那样。当然,按钮在这两帧中超出了范围,所以我无法观看。在下一个步骤中,我返回到txtContentBlockName\u TextChanged()
,按钮回到作用域中,但按钮。已启用的
已恢复为false。我没有任何其他涉及按钮属性的代码。如果重要的话,以下是在.aspx中声明按钮的方式:
<asp:Button ID="btnSaveContentBlockChanges" runat="server" Text="Save Changes" ToolTip="Save changes you've made to this content block" OnClick="btnSaveContentBlockChanges_Click" />
<asp:Button ID="btnDiscardContentBlockChanges" runat="server" Text="Discard Changes" ToolTip="Discard changes you've made to this content block" OnClick="btnDiscardContentBlockChanges_Click" />
感谢您提供的任何见解……谢谢。发现了问题。我正在使用
页面
的会话
属性来存储对用户第一次打开页面时填充的字段的引用。当我处理回发事件时,我从会话
还原这些字段。我遗漏的是页面
对象本身与用于填充字段的对象不同,因此这些字段中引用页面
对象中的任何内容都会引用旧的页面
。为了解决这个问题,我只需将subscribe代码移出if(!PostBack)
块,这样它就会出现在每个页面上