我正在尝试构建一个服务器控件,根据“QuestionTypeId”显示文本框,日期选择器或Yes-No单选按钮。
我的控件显示了我想要的内容,但是当在表单上按下提交按钮时,在RenderContents方法中生成的文本框,日期选择器或单选按钮都为空。
我试图将生成的控件存储在视图状态,这使得它们停止为null,但是没有存储用户输入。
如果需要,我会发布代码。请问。
答案 0 :(得分:1)
我认为您需要在CreateChildControls中创建(并添加)控件。这意味着您需要将QuestionTypeId的值存储在Viewstate或ControlState中(我认为ControlState在这种情况下适用,因为如果没有此值,您的控件将无法工作)。
答案 1 :(得分:0)
当您动态添加控件时,您需要确保在恢复视图状态之前重新创建它们。
我暂时没有这样做,但是从内存中我认为你应该在OnInit方法中重新创建控件。这是在加载回发数据之前和控件从viewstate设置其值之前发生的。
在asp.net页面生命周期中可能值得一些阅读:
答案 2 :(得分:0)
您可以为textbox,datepicker,radiobuttons创建用户控件并使用服务器控件。
如果您创建了一个cusom服务器控件,则必须将发布的数据添加到控件属性中。您可以在控制OnInit事件中执行此操作:
MyProperty = Request.Form("myControl");
答案 3 :(得分:0)
更简单的方法是在设计时创建所有控件,并根据您的要求使控件不可见。
示例代码:
protected void Page_Load(object sender, EventArgs e)
{
txtBox.Visible = QuestionTypeID == 1;
chkBox.Visible = QuestionTypeID == 2;
}
如果你确实使用动态控件,你应该像David所指出的那样,在ViewState或ControlState中保存值QuestionTypeID,然后根据该值创建你想要的控件。
(每次页面加载时甚至在帖子后面都需要创建控件,如果你希望他们的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 */
}
P.S。
使用动态控件来指定ID总是一个好主意
您可以将添加的控件保存到成员变量,并在别处使用它们(在分配后)
您可以订阅他们的活动,如果用户发布了新值,您的方法将被称为
答案 4 :(得分:0)
我已按照您的建议完成以下操作:
1)问题类型以视图状态存储在我的服务器控件中。
2)在CreateChildControls上,现在创建一个新的控件实例,并将其添加到页面上的占位符。
我现在的问题是事情好像有点奇怪:
1)在初始加载页面时,会触发创建子控件并触发我的服务器控件的RenderContents方法。
2)单击一个按钮以加载新的联系人,这会触发创建子控件并触发RenderContents。
3)输入详细信息并按下保存,这将触发创建子控件,但不会触发RenderContents,并且通过尝试访问我的控件以获取值来生成NullReferenceException。 (如果我跳过访问我的控件的代码,则调用RenderContents并渲染。
Seconly,另一个问题是,当我尝试设置一个值(onDataBind)时,我尝试访问在我的服务器控件中生成的文本框并获取另一个NullReferanceExeption
思想?