1

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

<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);
    }

提前致谢

4

1 回答 1

2

我确实相信您的问题在于不幸的是您需要在每次回发时重新加载动态控件。

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

于 2013-01-04T15:28:11.277 回答