我正在更新自定义事件处理程序中的WebForms控件的属性,但是当控件从事件处理程序返回时,属性将恢复为原来的状态。
以下是代码隐藏的相关部分:
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_TextChanged()
)。在ContentBlock
对象中,当我设置属性(在本例中为Name
)时,setter会验证它实际上是一个更改,然后触发在类中定义的NeedsCommitChanged
事件,此Page对象以ContentBlock_NeedsCommitChanged
作为处理程序订阅。处理程序(除其他外)根据数据是否需要提交到数据库来更新保存和丢弃按钮的状态。到目前为止,这么好......这一切都有效。
这就是问题所在:在ContentBlock_NeedsCommitChanged()
返回和控制权传递回txtContentBlockName_TextChanged()
之间的某个时刻,按钮的启用状态更改将恢复为false。我设置了如上所示的断点,然后我在断点位置B单步执行,然后在离开TextChanged处理程序的控制权之前在位置A处中断。我对按钮控件进行了监视,并将Enabled属性设置为true。我保持单步执行 - 控制传递回ContentBlock_NeedsCommitChanged()
并且Enabled属性仍然是真的。另一个步骤将我带到ContentBlock.OnNeedsCommitChanged()
然后转到ContentBlock.Name
设置器,就像我期望的那样。当然,按钮超出了这两个框架的范围,所以我无法观看它。在下一步中,我返回txtContentBlockName_TextChanged()
,按钮返回范围,但button.Enabled
已恢复为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" />
欣赏任何见解......谢谢。
答案 0 :(得分:0)
发现问题。我正在使用Page
的{{1}}属性来存储对用户第一次调出页面时填充的字段的引用。当我处理PostBack事件时,我会从Session
恢复这些字段。我错过的是Session
对象本身与用于填充字段的对象不同,因此引用Page
对象中某些内容的那些字段中的任何内容都引用旧的Page
。要解决此问题,我只需将订阅代码移出Page
块,以便它在每个if (!PostBack)
上发生。