ASP.NET:防止用户控件消失

时间:2013-01-04 15:22:13

标签: asp.net user-controls treeview

在我的网页上,我尝试在树视图中添加依赖于复选框的用户控件元素。因此,我创建了一个包含树视图的表和一个应该加载这些元素的面板。结构是这样的:

<asp:Content ID="BodyContent" runat="server" ContentPlaceHolderID="MainContent"> 
    <script language="javascript" type="text/javascript">
        function doCheckBoxPostBack(e) {
            var event = window.event ? window.event.srcElement : e.target;

            if (event.tagName == "INPUT" && event.type == "checkbox")
                __doPostBack("", "");
        }
    </script>
    <form id="form1" runat="server">
        <h1>Status</h1>    
        <div>     
            <asp:ScriptManager ID="ScriptManager1" runat="server">
            </asp:ScriptManager> 
            <table>
                <tr>
                    <td colspan="2" align="left" style="font-size:large">
                    Auswahl der anzuzeigenden Areas
                    </td>
                </tr>
                <tr>                
                    <asp:UpdatePanel ID="UpdatePanel1" runat="server" UpdateMode="Conditional">                
                        <ContentTemplate>                        
                            <td valign="top">
                                <asp:TreeView ID="tvAreaSelect" runat="server" 
                                    onclick="doCheckBoxPostBack(event)" ShowCheckBoxes="All" 
                                    ontreenodecheckchanged="tvAreaSelect_TreeNodeCheckChanged"> 
                                    <DataBindings>
                                        <asp:TreeNodeBinding DataMember="System.Data.DataRowView" TextField="Text" ValueField="ID" />
                                    </DataBindings>       
                                </asp:TreeView>
                            </td> 
                            <td>                                 
                                <div style="overflow:auto; height:740px;">
                                    <asp:Panel ID="panelContent" runat="server">                  
                                    </asp:Panel> 
                                </div>
                            </td>                       
                        </ContentTemplate>            
                    </asp:UpdatePanel>
                </tr>
            </table>                       
        </div>           
    </form>
</asp:Content>

在后面的代码中,只要其中一个复选框更改其Checked值,我就会加载或卸载我的用户控件。这就像它应该的那样工作,但是当我按下其中一个控件中的任何按钮时,所有这些按钮都会消失。我是否必须将它们保留在缓存中,还是有其他东西可以参加?

这是我的代码的一部分。我希望它能说清楚我在做什么。

protected void Page_Load(object sender, EventArgs e)
    {
        if (AreaIds.currList == null)            
            AreaIds.currList = new List<int>();

        if (!this.Page.IsPostBack)
        {  
            DataSet dsAreaGroups = dbStat.getDataSetAreaGroups();
            DataSet dsAreasNotInAreaGroups = dbStat.getDataSetAreasNotInAreaGroups();
            DataSet dsAreasInGroups = dbStat.getDataSetAreaGroupsWithAreas();

            DataSet dsTree = new DataSet();
            dsTree.Tables.Add("Table");
            dsTree.Tables[0].Columns.Add("ID", typeof(string));
            dsTree.Tables[0].Columns.Add("ParentID", typeof(string));
            dsTree.Tables[0].Columns.Add("Text", typeof(string));

            DataTableReader dtr = dsAreaGroups.CreateDataReader();

            while (dtr.Read())
            {
                DataRow row = dsTree.Tables[0].NewRow();
                object[] vals = new object[dtr.FieldCount];
                dtr.GetValues(vals);

                int inAreaGroupID = (int)vals.ElementAt(0);
                string stName = (string)vals.ElementAt(1);

                row["ID"] = inAreaGroupID;
                row["Text"] = stName;

                dsTree.Tables[0].Rows.Add(row);
            }

            dtr = dsAreasInGroups.CreateDataReader();

            while (dtr.Read())
            {
                DataRow row = dsTree.Tables[0].NewRow();
                object[] vals = new object[dtr.FieldCount];
                dtr.GetValues(vals);

                int inAreaID = (int)vals.ElementAt(0);
                int inAreaGroupID = (int)vals.ElementAt(1);
                string stName = (string)vals.ElementAt(2);

                string stCombo = inAreaGroupID + "-" + inAreaID;
                row["ID"] = stCombo;
                row["ParentID"] = inAreaGroupID;
                row["Text"] = stName;

                dsTree.Tables[0].Rows.Add(row);
            }

            dtr = dsAreasNotInAreaGroups.CreateDataReader();

            while (dtr.Read())
            {
                DataRow row = dsTree.Tables[0].NewRow();
                object[] vals = new object[dtr.FieldCount];
                dtr.GetValues(vals);

                int inAreaID = (int)vals.ElementAt(0);
                string stName = (string)vals.ElementAt(1);

                row["ID"] = "0-" + inAreaID;
                row["Text"] = stName;

                dsTree.Tables[0].Rows.Add(row);
            }

            tvAreaSelect.SetDataSourceFromDataSet(dsTree, "ID", "ParentID");
            tvAreaSelect.DataBind();
        }            
        }        

    public void includeAreas(List<int> areaId)
    {
        int[] array = areaId.ToArray();

        for (int i = 0; i < array.Length; i++)            
        {
            Control ctrl = LoadControl("StatusArea.ascx", areaId[i]);                
            this.panelContent.Controls.Add(ctrl);
        }
    }

    /// <summary>
    /// Bereitstellung eines UserControl aus einer ascx-Datei
    /// </summary>
    /// <param name="UserControlPath">Das UserControl ascx-Datei</param>
    /// <param name="constructorParameters">Parameter im Konstruktor der ascx.cs-Datei</param>
    /// <returns>UserControl mit den entsprechenden Parametern</returns>   
    private UserControl LoadControl(string UserControlPath, params object[] constructorParameters)
    {
        List<Type> constParamTypes = new List<Type>();
        foreach (object constParam in constructorParameters)
        {
            constParamTypes.Add(constParam.GetType());
        }

        UserControl ctl = Page.LoadControl(UserControlPath) as UserControl;

        // Find the relevant constructor
        System.Reflection.ConstructorInfo constructor = ctl.GetType().BaseType.GetConstructor(constParamTypes.ToArray());

        //And then call the relevant constructor
        if (constructor == null)
        {
            throw new MemberAccessException("The requested constructor was not found on : " + ctl.GetType().BaseType.ToString());
        }
        else
        {
            constructor.Invoke(ctl, constructorParameters);
        }

        // Finally return the fully initialized UC
        return ctl;
    }

    protected void tvAreaSelect_TreeNodeCheckChanged(object sender, TreeNodeEventArgs e)
    {
        TreeNode selNode = (TreeNode)e.Node;
        TreeNode parentNode = selNode.Parent;

        if (selNode.Checked && selNode.ChildNodes.Count == 0)
        {
            string stTest = selNode.Value.Substring(selNode.Value.IndexOf("-") + 1);
            int inAreaID = Convert.ToInt32(stTest);

            if (!AreaIds.currList.Contains(inAreaID))
                AreaIds.currList.Add(inAreaID);                
        }

        if (!selNode.Checked && selNode.ChildNodes.Count == 0)
        {
            string stTest = selNode.Value.Substring(selNode.Value.IndexOf("-") + 1);
            int inAreaID = Convert.ToInt32(stTest);

            if (AreaIds.currList.Contains(inAreaID))
                AreaIds.currList.Remove(inAreaID);                
        }

        foreach (TreeNode childNode in selNode.ChildNodes)
        {
            if (selNode.Checked)
            {
                string stTest = childNode.Value.Substring(childNode.Value.IndexOf("-") + 1);
                int inAreaID = Convert.ToInt32(stTest);

                childNode.Checked = true;

                if (!AreaIds.currList.Contains(inAreaID))
                    AreaIds.currList.Add(inAreaID);
            }
            else
            {
                string stTest = childNode.Value.Substring(childNode.Value.IndexOf("-") + 1);
                int inAreaID = Convert.ToInt32(stTest);

                childNode.Checked = false;

                if (AreaIds.currList.Contains(inAreaID))
                    AreaIds.currList.Remove(inAreaID);
            }
        }

        includeAreas(AreaIds.currList);
    }

提前致谢

1 个答案:

答案 0 :(得分:2)

我相信你的问题在于,遗憾的是你需要在每次回发时重新加载动态控件。

一种解决方案是保留“已加载”控件的会话中列表,并在Page_Init中重新创建它们。