我有一个自定义控件,我正在编写它来显示登录表单。“登录”按钮应根据实现它的页面执行不同的操作。因此,在页面代码隐藏中,我试图将控件中包含的登录按钮的命令事件设置为触发在页面代码隐藏。表单和一切都呈现正常,但单击登录按钮时未触发事件。
任何关于为什么 Command 事件没有触发的想法将不胜感激,谢谢!
控制代码“LoginForm.cs”
public enum LoginFormType
{
/// <summary>
/// Standard.
/// </summary>
[Description("Standard")]
Standard = 0,
/// <summary>
/// Customer Manager.
/// </summary>
[Description("Customer Manager")]
CustomerManager = 1,
}
public class LoginForm : Panel
{
public bool ShowInstructions = true;
public bool ShowForgotPassword = true;
public bool ShowRegisterLink = false;
public LoginFormType FormType = LoginFormType.Standard;
// inputs
public TextBox UsernameBox = new TextBox();
public TextBox PasswordBox = new TextBox();
// buttons
public Button LoginButton = new Button();
public Button ForgotPasswordButton = new Button();
// wrappers (<p> tags)
private HtmlGenericControl _InstructionsWrapper = new HtmlGenericControl("p");
private HtmlGenericControl _UsernameLabelWrapper = new HtmlGenericControl("p");
private HtmlGenericControl _UsernameBoxWrapper = new HtmlGenericControl("p");
private HtmlGenericControl _PasswordLabelWrapper = new HtmlGenericControl("p");
private HtmlGenericControl _PasswordBoxWrapper = new HtmlGenericControl("p");
private HtmlGenericControl _ButtonsWrapper = new HtmlGenericControl("p");
private HtmlGenericControl _RegisterWrapper = new HtmlGenericControl("p");
// literals (text)
private Literal _Instructions = new Literal();
private Literal _UsernameLabel = new Literal();
private Literal _PasswordLabel = new Literal();
private Literal _Register = new Literal();
private Literal _Spacer = new Literal();
// panels
private Panel _Errors = new Panel();
public LoginForm()
{
// IDs of dynamically added controls need to be declared here for scope
this._InstructionsWrapper.ID = "LoginFormInstructionsWrapper";
this._UsernameLabelWrapper.ID = "LoginFormUsernameLabelWrapper";
this._UsernameBoxWrapper.ID = "LoginFormUsernameBoxWrapper";
this._PasswordLabelWrapper.ID = "LoginFormPasswordLabelWrapper";
this._PasswordBoxWrapper.ID = "LoginFormPasswordBoxWrapper";
this._ButtonsWrapper.ID = "LoginFormButtonsWrapper";
this._RegisterWrapper.ID = "LoginFormRegisterLinkWrapper";
this.UsernameBox.ID = "LoginFormUsernameBox";
this.PasswordBox.ID = "LoginFormPasswordBox";
this.LoginButton.ID = "LoginFormLoginButton";
this.ForgotPasswordButton.ID = "LoginFormForgotPasswordButton";
}
public void DisplayError(string errorMessage)
{
Literal message = new Literal();
message.Text = errorMessage;
this._Errors.Controls.Add(message);
}
protected override void OnPreRender(EventArgs e)
{
base.CreateChildControls();
// element spacer
this._Spacer.Text = " ";
// instructions
if (this.ShowInstructions)
{
this._Instructions.Text = LoginFormResources.Instructions;
this._InstructionsWrapper.Controls.Add(this._Instructions);
this.Controls.Add(this._InstructionsWrapper);
}
// username label
this._UsernameLabel.Text = LoginFormResources.Username;
this._UsernameLabelWrapper.Controls.Add(this._UsernameLabel);
this.Controls.Add(this._UsernameLabelWrapper);
// username box
this._UsernameBoxWrapper.Controls.Add(this.UsernameBox);
this.Controls.Add(this._UsernameBoxWrapper);
// password label
this._PasswordLabel.Text = LoginFormResources.Password;
this._PasswordLabelWrapper.Controls.Add(this._PasswordLabel);
this.Controls.Add(this._PasswordLabelWrapper);
// password box
this.PasswordBox.TextMode = TextBoxMode.Password;
this._PasswordBoxWrapper.Controls.Add(this.PasswordBox);
this.Controls.Add(this._PasswordBoxWrapper);
// buttons
this.LoginButton.Text = LoginFormResources.Login;
this._ButtonsWrapper.Controls.Add(this.LoginButton);
if (this.ShowForgotPassword)
{
this._ButtonsWrapper.Controls.Add(this._Spacer);
this.ForgotPasswordButton.Text = LoginFormResources.ForgotPassword;
this._ButtonsWrapper.Controls.Add(this.ForgotPasswordButton);
}
this.Controls.Add(this._ButtonsWrapper);
// errors panel placeholder
this.Controls.Add(this._Errors);
// register link
if (this.ShowRegisterLink && this.FormType != LoginFormType.CustomerManager)
{
this._Register.Text = String.Format(LoginFormResources.Register, "<a href=\"register.aspx\">", "</a>");
this.Controls.Add(this._Register);
}
base.OnPreRender(e);
}
}
“Default.cs”页面代码隐藏
public class Default : CustomerManagerPage
{
public Content BreadcrumbContent = new Content();
public Content PageContent = new Content();
public Label Breadcrumb = new Label();
public LoginForm LoginFormControl = new LoginForm();
public Panel ForgotPasswordModal = new Panel();
public ModalPopupExtender ForgotPasswordMPE = new ModalPopupExtender();
protected override void OnInit(EventArgs e)
{
base.OnInit(e);
}
public void Page_Load(object sender, EventArgs e)
{
LoginFormControl.FormType = LoginFormType.CustomerManager;
LoginFormControl.ShowInstructions = true;
LoginFormControl.ShowRegisterLink = true;
LoginFormControl.LoginButton.Command += new CommandEventHandler(this._LoginButton_Command);
_BuildForgotPasswordModal();
if (IsPostBack)
{ }
}
private void _LoginButton_Command(object sender, CommandEventArgs e)
{
Response.Write("FIRED");
/*
try
{
Library.Login.AuthenticateUser(LoginFormControl.UsernameBox.Text, LoginFormControl.PasswordBox.Text);
Response.Redirect("/");
}
catch (Exception ex)
{
LoginFormControl.DisplayError(ex.Message);
}
*/
}
private void _BuildForgotPasswordModal()
{
this.ForgotPasswordMPE.ID = "ForgotPasswordMPE";
// header
Panel header = new Panel();
Label headerTitle = new Label();
headerTitle.ID = "ModalHeaderTitle";
headerTitle.Text = "Confirm";
header.ID = "ModalHeader";
header.CssClass = "ModalHeader";
header.Controls.Add(headerTitle);
// body
Label forgotPasswordText = new Label();
TextBox usernameBox = new TextBox();
Button forgotPasswordSubmitButton = new Button();
Button cancelButton = new Button();
Panel body = new Panel();
Panel hr = new Panel();
forgotPasswordText.ID = "ForgotPasswordText";
forgotPasswordText.Text = "<p>Enter your username in the box below, then click 'Submit'.</p> <p>Your password will be reset and emailed to the email address associated with your account.</p>";
usernameBox.ID = "ForgotPasswordUsername";
forgotPasswordSubmitButton.ID = "ForgotPasswordSubmit";
forgotPasswordSubmitButton.Text = "Submit";
cancelButton.ID = "ForgotPasswordCancel";
cancelButton.Text = "Cancel";
cancelButton.OnClientClick = "javascript:$find('" + ForgotPasswordMPE.ClientID + "').hide(); return false;";
hr.ID = "ModalHr";
hr.CssClass = "ModalHr";
body.ID = "ModalBody";
body.CssClass = "ModalBody";
body.Controls.Add(forgotPasswordText);
body.Controls.Add(usernameBox);
body.Controls.Add(hr);
body.Controls.Add(forgotPasswordSubmitButton);
body.Controls.Add(cancelButton);
// modal
this.ForgotPasswordModal.Controls.Add(header);
this.ForgotPasswordModal.Controls.Add(body);
// modal properties
this.ForgotPasswordModal.ID = "ForgotPasswordModal";
this.ForgotPasswordModal.CssClass = "ModalContainer";
// modal popup extender
this.ForgotPasswordMPE.TargetControlID = this.LoginFormControl.ForgotPasswordButton.ClientID;
this.ForgotPasswordMPE.PopupControlID = this.ForgotPasswordModal.ID;
this.ForgotPasswordMPE.OkControlID = forgotPasswordSubmitButton.ID;
this.ForgotPasswordMPE.CancelControlID = cancelButton.ID;
this.ForgotPasswordMPE.BackgroundCssClass = "ModalBackground";
}
}
“默认.aspx”
<% @ Page Language="C#" AutoEventWireup="true" Inherits="MyApplication.CustomerManager.Pages.Default" %>
<asp:Content ID="BreadcrumbContent" ContentPlaceHolderID="BreadcrumbContentPlaceholder" runat="server">
<asp:Label ID="Breadcrumb" runat="server" />
</asp:Content>
<asp:Content ID="PageContent" ContentPlaceHolderID="PageContentPlaceholder" runat="server">
<asp:ScriptManager ID="asm" runat="server" EnableScriptLocalization="true" EnableScriptGlobalization="true" />
<ctrls:LoginForm ID="LoginFormControl" runat="server" />
<asp:Panel ID="ForgotPasswordModal" runat="server"></asp:Panel>
<atk:ModalPopupExtender ID="ForgotPasswordMPE" runat="server" />
</asp:Content>
更新:问题已解决!
答案并不完全是生命周期,而是与生命周期有关。
首先,让控件从 Panel 继承(作为在 div 中呈现它的一种懒惰方式)是不对的。我将其更改为继承 WebControl 并将:base(HtmlTextWriterTag.Div) 添加到构造函数中,以便它呈现在 div 中。这是修复的次要部分。
此问题的实际解决方法是让控件也继承 INamingContainer。这是最重要的部分,显然对于控件子级引发回发事件是必要的。
此修复的第一部分只是必要的,因为即使在继承 INamingContainer 之后,它仍然无法正常工作。但是在将其更改为同时继承 WebControl 和 INamingContainer 之后,它就起作用了。仍然不太清楚为什么我不能继承 Panel 和 INamingContainer,但在这一点上,我不确定我是否足够关心来研究它。