【问题标题】:MSDN example of Composite Control复合控件的 MSDN 示例
【发布时间】:2011-02-23 03:14:33
【问题描述】:

我正在阅读有关复合控件的一些 MSDN 示例代码,发现有一件事我不明白。使用代码here 我在我的项目中创建了LabelTextBox 控件并将其添加到页面中。如果我在控件的文本框中输入一个新值,当我回发到服务器时,按钮单击事件具有旧值。如果我允许页面继续处理页面完成重新加载新值。这是一个糟糕的例子还是我错过了什么?不应该在按钮事件触发之前将更改的值加载到控件中吗?

复合控制代码:

public class LabelTextBox : WebControl, INamingContainer
{
    public string Text
    {
        get
        {
            object o = ViewState["Text"];
            if (o == null)
                return String.Empty;
            return (string)o;
        }
        set { ViewState["Text"] = value; }
    }
    public string Title
    {
        get
        {
            object o = ViewState["Title"];
            if (o == null)
                return String.Empty;
            return (string)o;
        }
        set { ViewState["Title"] = value; }
    }
    protected override void CreateChildControls()
    {
        Controls.Clear();
        CreateControlHierarchy();
        ClearChildViewState();
    }
    protected virtual void CreateControlHierarchy()
    {
        TextBox t = new TextBox();
        Label l = new Label();
        t.Text = Text;
        l.Text = Title;
        Controls.Add(l);
        Controls.Add(t);
    }
}

我尝试以声明方式和编程方式创建控件,但结果没有任何变化。程序化创建代码:

public partial class _Default : System.Web.UI.Page
{
    protected void Page_Load(object sender, EventArgs e)
    {
        Form.Controls.Add(new LiteralControl("<br /><br />"));

        TextBox tb = new TextBox();
        tb.Text = "before";
        Form.Controls.Add(tb);

        Form.Controls.Add(new LiteralControl("<br /><br />"));

        LabelTextBox ltb = new LabelTextBox();
        ltb.Title = "title";
        ltb.Text = "before";
        Form.Controls.Add(ltb);


    }

    protected void Button1_Click(object sender, EventArgs e)
    {
        foreach( var c in Form.Controls)
        {
            var control = c as TextBox;
            if (control != null) 
            {
                System.Diagnostics.Debug.WriteLine(String.Format("TextBox: {0}", control.Text)); 
            }
            else
            {
                var control2 = c as LabelTextBox;
                if (control2 != null)
                {
                    System.Diagnostics.Debug.WriteLine(String.Format("LabelTextBox: {0}", control2.Text));
                }
            }
        }
    }
}

【问题讨论】:

    标签: asp.net composite-controls


    【解决方案1】:

    我认为您的第一种方法的问题是您将值保留在父视图状态中,但从不从孩子那里读取值。尝试类似:

    public class LabelTextBox : WebControl, INamingContainer
    {
        private Label _Label     = new Label() { ID="uxLbl" };
        private TextBox _TextBox = new TextBox() { ID="uxTb" };
    
        public string Text
        {
            get { return _TextBox.Text; }
            set { _TextBox.Text = value; }
        }
        public string Title
        {
            get { return _Label.Text; }
            set { _Label.Text = value; }
        }
        protected override void CreateChildControls()
        {
            Controls.Clear();
            CreateControlHierarchy();
        }
        protected virtual void CreateControlHierarchy()
        {
            Controls.Add(_Label);
            Controls.Add(_TextBox);
        }
    }
    

    【讨论】:

    • 这似乎行得通。我想知道为什么复合控件的所有 MSDN 示例都显示了从 ViewState 获取和设置的属性呢?
    • @Shea:恕我直言——您提供的链接中的示例是复合控件的 terrible 示例。没有必要把它弄得这么复杂。但是,它对您不起作用的原因是,在文章的后面还有更多您没有包含在代码中的代码,例如 LoadPostbackData 方法。就像我说的那样,这是一个不好的例子——不要担心遵循它。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多