Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/asp.net/31.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Asp.net 创建自定义服务器控件以接受用户输入_Asp.net_Postback_Servercontrols - Fatal编程技术网

Asp.net 创建自定义服务器控件以接受用户输入

Asp.net 创建自定义服务器控件以接受用户输入,asp.net,postback,servercontrols,Asp.net,Postback,Servercontrols,我试图构建一个服务器控件,根据“QuestionTypeId”显示文本框、日期选择器或是否单选按钮 我的控件显示了我希望它显示的方式,但是当在表单上按下submit按钮时,RenderContents方法中生成的文本框、日期选择器或单选按钮都为空 我试图将生成的控件存储在视图状态,这使它们不再为null,但没有存储用户输入 我会张贴代码,如果需要的话。只要问一下。动态添加控件时,需要确保在恢复viewstate之前重新创建控件 我已经有一段时间没有这样做了,但根据记忆,我认为您应该在OnInit

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

我的控件显示了我希望它显示的方式,但是当在表单上按下submit按钮时,RenderContents方法中生成的文本框、日期选择器或单选按钮都为空

我试图将生成的控件存储在视图状态,这使它们不再为null,但没有存储用户输入


我会张贴代码,如果需要的话。只要问一下。

动态添加控件时,需要确保在恢复viewstate之前重新创建控件

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

有关asp.net页面生命周期的内容可能值得一读:


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

您可以创建一个用户控件,并使用服务器控件来创建文本框、日期选择器和单选按钮

如果创建cusom服务器控件,则必须将发布的数据添加到控件属性中。您可以在control OnInit事件中执行此操作:

MyProperty = Request.Form("myControl");

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

示例代码:

protected void Page_Load(object sender, EventArgs e)
{
    txtBox.Visible = QuestionTypeID == 1;
    chkBox.Visible = QuestionTypeID == 2;
}
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 */
}
如果确实使用动态控件,则应按照David指出的那样,将值QuestionTypeID保存在ViewState或ControlState中,然后根据该值创建所需的控件

(即使在回发中,每次加载页面时都需要创建控件,并且无法在页面生命周期的后期创建控件,如果希望保存和恢复控件的ViewState,请使用page_Load方法)

示例代码:

protected void Page_Load(object sender, EventArgs e)
{
    txtBox.Visible = QuestionTypeID == 1;
    chkBox.Visible = QuestionTypeID == 2;
}
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总是一个好主意。
您可以将添加的控件保存到成员变量中,并在其他位置使用它们(分配后)

您可以订阅他们的活动,如果用户发布了一个新值,您的方法将被调用

我已按照您的建议执行了以下操作:

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

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

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

1) 在页面的初始加载时,会激发create child控件,并激发my server控件的RenderContents方法

2) 单击按钮以加载新联系人,这将触发创建子控件并触发RenderContent

3) 输入详细信息并按save,这将触发创建子控件,但不会触发RenderContents,并通过尝试访问my控件以获取值生成NullReferenceException。(如果跳过访问控件的代码,将调用并渲染RenderContents

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


想法?

这正是ControlState适用的原因——因为没有值,控件无法工作。