C# 在运行时创建带有图像和链接按钮的面板

C# 在运行时创建带有图像和链接按钮的面板,c#,asp.net,linq,html,treeview,C#,Asp.net,Linq,Html,Treeview,我有一个有Treeview的主页。您可以在那里选择一些节点。 根据您在Default.aspx的占位符中选择的某些项目,您将在面板中获得一个图像和一个链接按钮。像这样: 此代码位于包含母版页的Default.aspx中 TreeView nav_tree = ((TreeView)Master.FindControl("treeview_Navigation")); string selectedNode = nav_tree.SelectedNode.Val

我有一个有Treeview的主页。您可以在那里选择一些节点。 根据您在Default.aspx的占位符中选择的某些项目,您将在面板中获得一个图像和一个链接按钮。像这样:

此代码位于包含母版页的Default.aspx中

        TreeView nav_tree = ((TreeView)Master.FindControl("treeview_Navigation"));
        string selectedNode = nav_tree.SelectedNode.Value;

        var query = from n in dc.Nemanet_Navigations
                    where n.UserId == userGuid && n.Nav_pID.ToString() == selectedNode && n.Nav_IsFile == false
                    orderby n.Nav_Name
                    select n;
        foreach (var item in query)
        {

            Panel div = new Panel();
            div.ID = item.Nav_ID.ToString();
            div.CssClass = "BulletDiv";
            content_default.Controls.Add(div);

            Image picture = new Image();
            picture.ImageUrl = "~/Icons/New_Folder.png";
            div.Controls.Add(picture);

            div.Controls.Add(new LiteralControl("<br/>"));

            LinkButton description = new LinkButton();
            description.Text = item.Nav_Name;
            description.PostBackUrl = "default.aspx";
            div.Controls.Add(description);

        }
TreeView nav_tree=((TreeView)Master.FindControl(“TreeView_导航”);
字符串selectedNode=nav_tree.selectedNode.Value;
var query=在dc.Nemanet\u导航中从n开始
其中n.UserId==userGuid&&n.Nav\u pID.ToString()==selectedNode&&n.Nav\u IsFile==false
orderby n.Nav_名称
选择n;
foreach(查询中的var项)
{
面板div=新面板();
div.ID=item.Nav_ID.ToString();
div.CssClass=“BulletDiv”;
content\u default.Controls.Add(div);
图像图片=新图像();
picture.ImageUrl=“~/Icons/New_Folder.png”;
div.Controls.Add(图片);
添加(新的LiteralControl(“
”); LinkButton description=新建LinkButton(); description.Text=item.Nav_Name; description.PostBackUrl=“default.aspx”; div.Controls.Add(说明); }
当我在运行时创建控制器时,当站点进行回发时,似乎出现了问题,比如说,如果我在树视图中单击“Enska”,我将在上图中得到结果。假设我点击“朋克黑豹”,我得到一个错误

发生了一个错误,因为 id为“ctl00$CPH_Main$ctl05”的控件 找不到或找不到其他文件 控件被分配给相同的ID 回邮后。如果ID不是 赋值,显式设置ID 引发的控件的属性 回发事件以避免此错误

另外,我如何在运行时为linkbutton创建一个事件处理程序,我可以为每个linkbutton创建一个事件处理程序吗?
我希望文件夹和链接按钮可以单击并链接到同一个位置,使整个面板可以单击是否更简单,如果是这样,如何在其上获得“OnClick”事件?

您的问题与有时难以理解的问题有关

在回发请求期间,不会在页面生命周期的正确点重新创建运行时创建的控件层次结构(如果有)

其他web控件(如DataGrid)解决此问题的“经典”方法是将加载到控件中的数据序列化到viewstate中,以便在回发时,可以仅从回发值重建控件层次结构(无需再次查询数据库)。然而,在您的环境中实施这种方法可能并不合适

相反,您可以构建用于构建以前的控件层次结构的
item
键值(
item.Nav_ID
)的数组(或其他可序列化枚举),并将其添加到viewstate,例如:

List<Int32> navIdValues = new List<Int32>();
foreach (var item in query)
{
    navIdValues.Add(item.Nav_ID);
}
Page.ViewState("NavIdValues") = navIdValues
重新执行查询,建立一个可通过其
导航ID
访问的项目字典:

IDictionary<Int32, ??itemtype??> items = query.ToDictionary(n => n.Nav_Id);
然后,回发事件应按预期触发,因为在回发事件处理之前已重新创建控件层次结构。这可能不是最理想的解决方案,但却是可行的

IDictionary<Int32, ??itemtype??> items = query.ToDictionary(n => n.Nav_Id);
foreach (Int32 navId in navIdValues)
{
     var item = items(navId); 

     Panel div = new Panel();
     div.ID = item.Nav_ID.ToString();
     div.CssClass = "BulletDiv";

     ... etc ...
}