在我的网页上,我尝试在树视图中添加依赖于复选框的用户控件元素。因此,我创建了一个包含树视图的表和一个应该加载这些元素的面板。结构是这样的:
<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);
}
提前致谢
答案 0 :(得分:2)
我相信你的问题在于,遗憾的是你需要在每次回发时重新加载动态控件。
一种解决方案是保留“已加载”控件的会话中列表,并在Page_Init中重新创建它们。