我正在编写一个自定义控件来显示登录表单。 “登录”按钮应该根据它实现的页面执行不同的操作。因此,在页面代码隐藏中,我试图设置控件中包含的登录按钮的Command事件来触发在页面代码隐藏。表单和所有内容都可以正常显示,但单击“登录”按钮时,事件不会触发。
非常感谢任何有关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);
}
}
Page Codebehind“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";
}
}
“的Default.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,但在这一点上我不确定我是否足够仔细研究它。