多个控制实例导致按钮干扰

时间:2012-07-13 14:07:59

标签: c# umbraco webforms custom-data-type

一点背景:

我一直在为Umbraco开发自定义数据类型。数据类型显示特定类型的节点列表,并允许用户从此列表中进行选择。我试图使这种数据类型可重用,这样我就不必为我希望列出的每种类型的节点创建一个单独的数据类型。我只需创建此数据类型的属性并设置要显示的节点类型。

数据类型是一个UpdatePanel,它包含一个复选框列表(对于每个要选择的节点)和一个用于在选择中添加/删除这些节点的按钮。

例如,如果我有一个帖子,我可以添加此数据类型并将其设置为列表类别,这允许我将帖子与类别列表相关联。如果我想要拥有此数据类型的另一个实例,比如选择作者,我就会开始遇到问题。

数据类型结构信息

这应该更详细地说明如何构建此控件。它使用创建umbraco数据类型的3 classes method,因此我没有.ascx文件,只是一个以编程方式将元素呈现到页面上的.cs文件。

通过迭代节点列表并呈现以下内容来呈现复选框:

<input type='checkbox' name='select_nodes' value='" + n.Id + "' />

然后我渲染两个按钮,一个用于将节点添加到所选节点列表,另一个用于删除它们(我只是在这里显示添加)。此按钮只获取Form [&#34; select_nodes&#34;]的值,其中包含逗号分隔的节点ID列表,并为每个节点添加到单独节点列表中。

按钮添加如下:

public override void OnInit(EventArgs e)
{
    //Add Button
    btn_Add = new Button();
    btn_Add.CssClass = "btn_add";
    btn_Add.ID = "btnAdd" + Guid.NewGuid();
    btn_Add.Text = "Add >>";
    btn_Add.Click += new EventHandler(selectNodes);
    base.ContentTemplateContainer.Controls.Add(btn_Add);
}

上面以基本形式描述了这个控件,希望能够更深入地了解设置。

问题

在加载具有此数据类型的多个实例的节点时,如上例所示,由于重复的控件ID而发生错误,我通过向id附加随机guid来克服此错误。现在的问题是选择/取消选择节点的按钮似乎不起作用。我假设它是由于这些按钮有多个实例,并且与哪个事件发生混淆?

有没有办法解决这个问题?为了避免干扰多个控件实例?

谢谢,

3 个答案:

答案 0 :(得分:1)

答案 1 :(得分:1)

我认为问题是每次页面回发时都会再次生成控件,并且由于每次都会附加Guid.NewGuid(),因此它们会以不同的ID结束。当页面回发时,它会为你单击的按钮运行一个findcontrol,然后从中获取事件处理程序,但是如果按钮的ID已经改变,它将无法找到它,并且随后找不到它的事件处理程序。

使这种情况起作用的最佳方法是不生成随机字符串以附加到控件名称,而是使用可在按钮创建的上下文中控制的已知常量。因此,如果它是列表项的按钮,则每次都会向其附加“li”,或者类似的东西。然后你知道每个回发你的控件都有相同的名字 - 但它仍然是它自己的实例所独有的。

答案 2 :(得分:0)

<强>成功

正如@Infotekka在下面的评论中所指出的那样:

  

我认为问题是你的控件每次都会再次生成   页面帖子回来了,因为它们最终得到了不同的ID   Guid.NewGuid()每次都会被追加。当页面回发时   它为你点击的按钮运行一个findcontrol然后得到   事件处理程序,但如果按钮的ID已更改,则不会   找到它,然后找不到它的事件处理程序

作为回应,我换了:

btn_Add.ID = "btnAdd" + Guid.NewGuid();

btn_Add.ID = "btnAdd_" + targetDocType.ToLower();

继上面的示例之后,这将导致此控件/数据类型的一个实例带有带有ids“btnAdd_Category”和“btnRemove_Category”的添加/删除按钮,而在另一个实例中会出现“btnAdd_Author”和“btnRemove_Author”。 / p>

最初这没有解决问题,但是在进一步调查中,我有一个LiteralControl我正在添加到页面中以包含一些嵌入式css,并且每个实例也需要这个id。

感谢@Infotekka指出了问题的根源,并感谢@dludlow的链接!

@Infotekka,如果您发布之前的评论作为答案,我可以将其标记为答案:)