在运行时使用图像和链接按钮创建面板

时间:2010-07-14 10:39:55

标签: c# asp.net linq html treeview

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

alt text http://a.imageshack.us/img20/9206/foldersrb.jpg

此代码位于具有母版页的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);

        }

当我在运行时创建控制器时,似乎有问题,当站点进行回发时,假设我在树视图中单击“Enska”,我会在上面的图像中得到结果。让我们说,然后我点击“朋克黑豹”我得到一个错误。

  

因为a而发生错误   控制ID为'ctl00 $ CPH_Main $ ctl05'   无法定位或不同   控件被分配给相同的ID   回发后。如果ID不是   已分配,明确设置ID   提升的控制的财产   回发事件以避免此错误。

另外,我如何通过在运行时为linkbutton创建事件处理程序,我可以创建一个每个linkbutton使用的事件处理程序或什么? 我希望文件夹和链接按钮可以点击并链接到同一个地方,是否更简单地使整个Panel可点击,如果是这样,我将如何获得“OnClick”事件?

1 个答案:

答案 0 :(得分:1)

您的问题与有时难以理解的ASP.NET Page Lifecycle有关。

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

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

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

List<Int32> navIdValues = new List<Int32>();
foreach (var item in query)
{
    navIdValues.Add(item.Nav_ID);
}
Page.ViewState("NavIdValues") = navIdValues

然后,在传入回发的Page.Init事件期间,检索您在上一个请求中用于构建控件层次结构的值:

List<Int32> navIdValues = Page.ViewState("NavIdValues") as List<Int32>;

重新执行您的查询,构建可通过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 ...
}

然后您的回发事件应按预期触发,因为在回发事件处理之前已重新创建控件层次结构。这可能不是最佳解决方案,但是可行的解决方案。