【问题标题】:Creating custom server control to accept user input创建自定义服务器控件以接受用户输入
【发布时间】:2010-09-23 22:55:46
【问题描述】:

我正在尝试构建一个服务器控件,根据“QuestionTypeId”显示文本框、日期选择器或是-否单选按钮。

我可以控制显示我想要的方式,但是当在表单上按下提交按钮时,在 RenderContents 方法中生成的文本框、日期选择器或单选按钮都为空。

我试图将生成的控件存储在视图状态中,这阻止了它们为空,但没有存储用户输入。

如果需要,我会发布代码。随便问问。

【问题讨论】:

    标签: asp.net postback servercontrols


    【解决方案1】:

    当您动态添加控件时,您需要确保在恢复视图状态之前重新创建它们。

    我已经有一段时间没有这样做了,但根据记忆,我认为您应该在 OnInit 方法中重新创建控件。这发生在加载回发数据之前以及控件从视图状态设置其值之前。

    可能值得阅读一下 asp.net 页面生命周期:

    http://msdn.microsoft.com/en-us/library/ms178472.aspx

    【讨论】:

      【解决方案2】:

      我认为您需要在CreateChildControls 中创建(并添加)控件。这意味着您需要将 QuestionTypeId 的值存储在 Viewstate 或 ControlState 中(我认为 ControlState 在这种情况下适用,因为如果没有此值,您的控件将无法工作)。

      【讨论】:

      • 这正是 ControlState 适用的原因 - 因为没有该值,控件就无法工作。
      【解决方案3】:

      您可以为文本框、日期选择器、单选按钮创建用户控件并使用服务器控件。

      如果您创建一个自定义服务器控件,那么您必须将发布的数据添加到您的控件属性中。您可以在您的控件 OnInit 事件中执行此操作:

      MyProperty = Request.Form("myControl");
      

      【讨论】:

        【解决方案4】:

        更简单的方法是在设计时创建所有控件,并根据您的要求使控件不可见。

        示例代码:

        protected void Page_Load(object sender, EventArgs e)
        {
            txtBox.Visible = QuestionTypeID == 1;
            chkBox.Visible = QuestionTypeID == 2;
        }
        

        如果您确实使用动态控件,您应该按照 David 指出的那样做,将值 QuestionTypeID 保存在 ViewState 或 ControlState 中,然后根据该值创建所需的控件。

        (每次页面加载时都需要创建控件,即使在回发时也需要创建它们,并且它们不能在页面生命周期的后期创建,如果您希望它们的 ViewState 持久化和恢复,则使用 Page_Load 方法)

        示例代码:

        protected void Page_Load(object sender, EventArgs e)
        {
            var questionId = ViewState["QuestionTypeID"];
        
            if(questionId == /* Value to create TextBox */) {
                var txt = new TextBox { ID = "txt" };
                placeHolder.Controls.Add(txt);
            } else if(questionId == /* Value to create Calender */) {
                var cal = new Calender { ID = "cal" };
                placeHolder.Controls.Add(cal);
            }
        
            /* Once the controls are added they will be populated with the posted values */
        }
        

        附言
        使用动态控件指定 ID 总是一个好主意。
        您可以将添加的控件保存到成员变量中并在其他地方使用它们(分配后)
        您可以订阅他们的事件,如果用户发布了新值,您的方法将被调用

        【讨论】:

          【解决方案5】:

          我听从了你的建议,做了以下事情:

          1) 问题类型以视图状态存储在我的服务器控件中。

          2) 现在在 CreateChildControls 上创建我的控件的新实例并将其添加到页面上的占位符。

          我现在的问题是事情似乎有点奇怪:

          1)在页面初始加载时,会触发创建子控件并触发我的服务器控件的 RenderContents 方法。

          2)单击按钮加载新联系人,这会触发创建子控件并触发 RenderContents。

          3) 输入详细信息并按下保存,这会触发 Create Child Controls 但不会触发 RenderContents,并且会通过尝试访问我的控件以获取值来生成 NullReferenceException。 (如果我跳过访问我的控件的代码,则会调用并呈现 RenderContents。

          其次,另一个问题是,当我尝试设置一个值 (onDataBind) 时,我尝试访问在我的服务器控件中生成的文本框并获取另一个 NullReferanceExeption

          想法?

          【讨论】:

            猜你喜欢
            • 2011-09-03
            • 1970-01-01
            • 1970-01-01
            • 2011-04-13
            • 1970-01-01
            • 2013-07-31
            • 1970-01-01
            • 2012-03-18
            • 2015-08-15
            相关资源
            最近更新 更多