自定义控件属性未正确初始化

时间:2010-12-14 00:40:34

标签: asp.net

第一个 - LblTextBox:  具有LabelText字段的标签和文本框,可以将其设置为更改标签文本

第二个 - LoginCtl:  一个登录控件,它有两个LblTextBox实例,用于输入用户名,密码和提交按钮

我想控制这些控件的标记呈现以进行格式化,因此我没有重写CreateChildControls()来完成工作。

我的问题是渲染控件,但两个控件中的OnInit()代码都没有占用(空白标签,未应用css样式等等)。

任何方向都会很棒!

public class LblTextBox : CompositeControl
{
    public string LabelText { get; set; }
    public string Text { get; set; }

    TextBox input;
    Label label;
    RequiredFieldValidator evalReqField;

    public LblTextBox()
    {
        label = new Label();
        input = new TextBox();
        evalReqField = new RequiredFieldValidator();
    }

    protected override void  OnInit(EventArgs e)
    {
        label.ID = "lblTextBox";
        label.Text = string.Format("{0}:", LabelText);

        input.ID = "tbInput";

        evalReqField.ID = "evalInput";
        evalReqField.ControlToValidate = input.ID;
        evalReqField.ErrorMessage = "(Required)";
        evalReqField.Display = ValidatorDisplay.Dynamic;
    }

    protected override void RenderChildren(HtmlTextWriter writer)
    {
        writer.RenderBeginTag(HtmlTextWriterTag.Div);
        label.RenderControl(writer);
        input.RenderControl(writer);
        evalReqField.RenderControl(writer);
        writer.RenderEndTag();
    }
}

public class LoginCtl : CompositeControl
{   
    public string UserName 
    { 
        get
        {
            return (ltbUser != null) ? ltbUser.Text : string.Empty;
        }
        set
        {
            if (ltbUser != null)
                ltbUser.Text = value; 
        }
    }

    public string Password 
    {
        get
        {
            return (ltbPass != null) ? ltbPass.Text : string.Empty;
        }
        set
        {
            if (ltbPass != null)
                ltbPass.Text = value;
        }
    }

    private LblTextBox ltbUser;
    private LblTextBox ltbPass;
    private Button btnSubmit;

    public LoginCtl()
    {
        ltbUser = new LblTextBox();
        ltbPass = new LblTextBox();
        btnSubmit = new Button();
    }

    protected override void  OnInit(EventArgs e)
    {
        ltbUser.LabelText = "User Name";
        ltbPass.LabelText = "Password";
        btnSubmit.Text = "Submit";
        btnSubmit.CssClass = "Submit";
    }

    protected override void RenderChildren(HtmlTextWriter writer)
    {
        writer.AddAttribute(HtmlTextWriterAttribute.Class, "LoginCtlDiv");
        writer.RenderBeginTag(HtmlTextWriterTag.Div);
        ltbUser.RenderControl(writer);
        ltbPass.RenderControl(writer);
        btnSubmit.RenderControl(writer);
        writer.RenderEndTag();
    }
}

2 个答案:

答案 0 :(得分:1)

目标是能够使用控件在aspx Markup中设置属性。但是,这些属性从未初始化。

我的错误在于使用CreateChildControls()和RenderChildren(..)的理解 我以为是使用其中一个。相反,我实例化所有子控件并将它们添加到CreateChildControls()。

为了加载属性,我等到OnPreRender()事件。控件将全部加载,数据也将加载。然后我在控件呈现到页面之前进行最后的更改。

另一个小注意事项,我真的想更改包含在我的控件周围的默认标记以用于显示目的(默认情况下,ASP将使用span包装它)。因此,如果您想要块级别elem,这将导致问题。如果重写TagKey属性并将其设置为枚举元素,它将使用它而不是默认的span标记。

我将其重组为以下内容:

public class LblTextBox : CompositeControl
{
    protected override void OnPreRender(EventArgs e)
    {
        label.Text = string.Format("{0}:", LabelText);
        base.OnPreRender(e);
    }

    protected override HtmlTextWriterTag TagKey
    {
        get
        {
            return HtmlTextWriterTag.Div;
        }
    }

    protected override void CreateChildControls()
    {
        label = new Label();
        input = new TextBox();
        evalReqField = new RequiredFieldValidator();

        label.ID = "lblTextBox";
        input.ID = "tbInput";
        evalReqField.ID = "evalInput";

        evalReqField.ControlToValidate = input.ID;
        evalReqField.ErrorMessage = "(Required)";
        evalReqField.Display = ValidatorDisplay.Dynamic;

        Controls.Add(label);
        Controls.Add(input);
        Controls.Add(evalReqField);
        base.CreateChildControls();
    }

    public string LabelText { get; set; } //label text
    public string Text { get; set; } //text in textbox

    TextBox input;
    Label label;
    RequiredFieldValidator evalReqField;
}


public class LoginCtl : CompositeControl
{
    protected override void CreateChildControls()
    {
        ltbUser = new LblTextBox();
        ltbPass = new LblTextBox();
        btnSubmit = new Button();

        ltbUser.LabelText = "User Name";
        ltbPass.LabelText = "Password";
        ltbPass.MargBetween = "10px";
        btnSubmit.Text = "Submit";
        btnSubmit.CssClass = "Submit";

        Controls.Add(ltbUser);
        Controls.Add(ltbPass);
        Controls.Add(btnSubmit);
    }

    //..
    //..

    private LblTextBox ltbUser;
    private LblTextBox ltbPass;
    private Button btnSubmit;

    protected override HtmlTextWriterTag TagKey
    {
        get
        {
            return HtmlTextWriterTag.Div;
        }
    }
 }

答案 1 :(得分:0)

我不记得为什么(我会记得),但几个月前我遇到了类似的问题,我的解决办法是在OnLoad事件处理程序中初始化除“ID”之外的所有属性:

protected override void OnLoad(EventArgs e)
{
        label.Text = string.Format("{0}:", LabelText);
        evalReqField.ControlToValidate = input.ID;
        evalReqField.ErrorMessage = "(Required)";
        evalReqField.Display = ValidatorDisplay.Dynamic;

}

希望这有帮助