首页 > 解决方案 > 在 asp.net 中创建动态控件并保留其状态

问题描述

我有两个数据表,一个用于问题,一个用于选项。现在要显示问题,我正在使用 FormView 控件,在此控件中,我绑定了问题及其选项。

现在有一些不同的问题类型,基于这些我需要生成不同的控件。

我找到了很多添加动态控件的解决方案,但不适合此操作。

现在让我粘贴用于呈现问题及其选项的代码..

<asp:FormView ID="fv_question_option" runat="server" AllowPaging="true" OnPageIndexChanging="fv_question_option_OnPageIndexChanging"
                        OnDataBound="fv_question_option_OnDataBound" PagerSettings-Visible="False">
                        <HeaderTemplate>
                            <table>
                                <tr style="color: #009900; font-weight: bold">
                                    <br />
                                </tr>
                                <tr style="color: #009900; font-weight: bold">
                                </tr>
                                <tr>
                                    <td>
                                        <br />
                                        <asp:Button ID="First" Text="First" Width="100px" CommandName="Page" CommandArgument="First" runat="server" CssClass="btn btn-primary" />
                                        &nbsp;&nbsp;&nbsp;
                                            <asp:Button ID="Prev" Text="Previous" Width="100px" runat="server" CommandName="Page" CommandArgument="Prev" CssClass="btn btn-primary" />&nbsp;&nbsp;&nbsp;
                                            <asp:Button ID="Next" Text="Next" Width="100px" runat="server" CommandName="Page" CommandArgument="Next" CssClass="btn btn-primary" />&nbsp;&nbsp;&nbsp;
                                            <asp:Button ID="Last" Text="Last" Width="100px" runat="server" CommandName="Page" CommandArgument="Last" CssClass="btn btn-primary" />&nbsp;&nbsp;&nbsp;
                                            <asp:Button ID="End" Text="End Test" OnClick="EndTest" Width="100px" runat="server" CssClass="btn btn-danger" />
                                        <br />
                                    </td>
                                </tr>
                            </table>
                            <hr />
                        </HeaderTemplate>
                        <ItemTemplate>
                            <table>
                                <tr>
                                    <td>
                                        <span style="font-weight: bolder;"><%#fv_question_option.PageIndex+1 %></span> <span style="font-weight: bold">)</span>
                                    </td>
                                    <td>
                                        <asp:Label runat="server" ID="lblQuestion" Font-Bold="True" Text='<%# DataBinder.Eval(Container.DataItem, "description")%>'></asp:Label>
                                        <asp:Label runat="server" Visible="False" ID="lblQType" Text='<%# DataBinder.Eval(Container.DataItem, "question_type_id")%>'></asp:Label>
                                         <asp:Label runat="server" Visible="False" ID="lblQId"  Text='<%# DataBinder.Eval(Container.DataItem, "question_id")%>'></asp:Label>
                                    </td>
                                </tr>
                            </table>
                            <table>
                                <tr>
                                    <td>
                                        <asp:Panel runat="server" ID="pnlOption" style="margin-top: 8px;margin-left: 21px"></asp:Panel>
                                    </td>
                                </tr>
                            </table>
                        </ItemTemplate>

                    </asp:FormView>

在后面的代码中

protected void fv_question_option_OnPageIndexChanging(object sender, FormViewPageEventArgs e)
        {

            fv_question_option.PageIndex = e.NewPageIndex;
            BindQuestionWithOption();
        }

        protected void fv_question_option_OnDataBound(object sender, EventArgs e)
        {
            // store dynamically created control'sID and value..
            DataTable dtUserOption = ViewState["dtOptionByUser"] as DataTable;
            ViewState["counter"] = ViewState["counter"] ?? 1;
            //DataRowView dataRow = ((DataRowView)fv_question_option.DataItem);
            DataTable dtOptions = ViewState["dtOptions"] as DataTable;
            string questId = ((Label)fv_question_option.FindControl("lblQId")).Text;
            string qtype = ((Label)fv_question_option.FindControl("lblQType")).Text;
            Panel pOpt = ((Panel)fv_question_option.FindControl("pnlOption"));
            DataTable dtOption =
                dtOptions.AsEnumerable()
                    .Where(r => r["question_id"].ToString() == questId && r["question_type_id"].ToString() == qtype)
                    .CopyToDataTable();
            switch (qtype)
            {
                case "1": // mcq
                    CheckBoxList chkbox = new CheckBoxList
                    {
                        ID = "ctrl" + Convert.ToInt16(ViewState["counter"]),
                        DataTextField = "option_text",
                        DataValueField = "choice_id",
                        DataSource = dtOption
                    };
                    chkbox.DataBind();
                    chkbox.RepeatDirection = RepeatDirection.Horizontal;
                    pOpt.Controls.Add(chkbox);
                    break;

                case "2": // TF
                    RadioButtonList rdoList = new RadioButtonList
                    {
                        ID = "ctrl" + Convert.ToInt16(ViewState["counter"]),
                        DataTextField = "option_text",
                        DataValueField = "choice_id",
                        DataSource = dtOption
                    };
                    rdoList.DataBind();
                    rdoList.RepeatDirection = RepeatDirection.Horizontal;
                    pOpt.Controls.Add(rdoList);
                    break;

                case "3": // text type 
                    TextBox tb = new TextBox()
                    {
                        ID = "ctrl" + Convert.ToInt16(ViewState["counter"]),
                        TextMode = TextBoxMode.MultiLine,
                        Rows = 2
                    };
                    pOpt.Controls.Add(tb);
                    break;

                case "6": // Fill the blanks
                    string questionText = ((Label)fv_question_option.FindControl("lblQuestion")).Text;
                    // get no of blanks here to rpint no of textboxes
                    int count = Regex.Matches(questionText, "_{3,}").Count;

                    for (int i = 0; i < count; i++)
                    {
                        TextBox tbFBox = new TextBox()
                        {
                            ID = "ctrl" + Convert.ToInt16(ViewState["counter"]),
                            TextMode = TextBoxMode.MultiLine,
                            Rows = 2,
                            CssClass = "blck"
                        };
                        ViewState["counter"] = (int)ViewState["counter"] + 1;
                        pOpt.Controls.Add(tbFBox);
                    }
                    break;
            }
            ViewState["counter"] = (int)ViewState["counter"] + 1;
        }

现在使用此代码,我可以分别显示问题及其选项,但无法找到保留其价值的方法。非常感谢你们提供的任何帮助。

编辑:如果使用这种方法无法做到这一点,那么我还能做什么?

标签: c#asp.net

解决方案


推荐阅读