【问题标题】:Adding click events to user control向用户控件添加点击事件
【发布时间】:2010-08-28 18:07:35
【问题描述】:

我在 asp.net Web 应用程序中有一个用户控件。控件输出一个根据当前登录用户定制的 html 列表。列表项是通过数据库查找生成的,并且用户控件的格式设置为在页面中显示为下拉列表。

控件本身很简单,如下所示:

<%@ Control Language="VB" AutoEventWireup="false" CodeFile="item-lector.ascx.vb" Inherits="includes_usercontrols_item_selector" %>
<!--Item Selector-->
<div id="item-selector">
<%=Me.Output%>
</div>

文件后面的代码动态填充控件的“输出”属性,因此最终标记如下所示:

<div id="item-selector">
<h1>Item 1 - Item 1</h1>  
<a href="#" class="changeItem  itemArrow">Change item</a>  
<ul id="changeItemMenu" class="dropDownMenu">    
<li><a href="#">Item 1</a></li>    
<li><a href="#">Item 2</a></li>    
<li><a href="#">Item 3</a></li>    
<li><a href="#">Item 4</a></li>    
<li><a href="#">Item 5</a></li>    
<li><a href="#">Item 6</a></li>    
<li><a href="#">Item 7</a></li>    
<li><a href="#">Item 8</a></li>    
<li><a href="#">Item 9</a></li>    
<li><a href="#">Item 10</a></li>    
</ul>
</div>

ID 和类属性都是格式化和其他脚本所必需的。该控件旨在用作选择器,页面的其余部分应对用户选择的项目做出反应。

我想要做的是将点击事件添加到列表项中。当用户单击列表中的一项时,我想捕获用户在列表中选择的哪个项目(这是否需要回发?)并在后面的代码中对其进行处理

我更像是一个中间层和数据库层的开发人员,UI 开发不是我的强项,所以在这方面请考虑我是新手。我不确定如何继续或将什么注入输出字符串以启用此功能。任何和所有的帮助将不胜感激!

【问题讨论】:

  • 您不需要回发到服务器来捕获用户选择的项目,您只需要客户端的Javascript代码。

标签: javascript asp.net html


【解决方案1】:

您可能不一定需要使用回发, 但如果你愿意,你需要使用一个叫做delegates的东西。
在这里查看:link

即使您不使用它们,它们也很有用,并且允许您将“自定义”事件添加到您的用户控件。


编辑:
以下是一些您可以使用的代码:
首先你定义你的委托类型。将委托想象为函数指针。 您将在代码隐藏中定义:

public delegate void OnChangeDelegate(object sender, EventArgs e);

然后将实际事件定义为OnChangeDelegate 类型。

public event OnChangeDelegate Change;

然后您创建一个(或两个)“触发”您的事件的方法:
(在您的 ascx.cs 文件中)

public void ItemChange(object sender, EventArgs e)
{
    if (sender != null && sender is LinkButton)
    {
        string idx = ((LinkButton)sender).CommandArgument;
        FireMyChangeEvent(sender, idx);
}

还有

private void FireMyChangeEvent(object sender, string index)
{
    if (MyItemChange != null)
    {
        EventArgs e = new EventArgs();

        Change(sender, new ItemSelectorEventArgs(index));
    }
}

因此,在您的代码隐藏中的任何位置,您都可以将句柄传递给控件以及 EventArgs 对象中的一些额外内容。

现在棘手的部分是让您的 &lt;li&gt; s 导致回发。 传统上,您将使用 &lt;select&gt;&lt;option&gt;s,因为本机 onclick 事件,但由于您正在渲染 &lt;ul&gt;&lt;li&gt;s 你可能想用&lt;asp:LinkButton runat="server"&gt; 包装它们,这样你就会触发一个事件,而不是&lt;a href="#"&gt;,所以你可以为那个LinkBut​​ton 说OnClick,在这种情况下,你可以调用你的ItemChange 方法触发控件的事件,并传递您可以在事件的 EventArgs 中发送的项目的 ID。

我绝对会推荐阅读我发送给您的链接,并记住,除非控件具有 runat="server",否则您的服务器将无法处理它。

**更新*:这里还有一些代码。

我的 ASPX 代码 请注意,WebUserControl1 是我的用户控件,MyClick 是 ASPX.cs 代码中定义的方法。

<ul>
    <uc1:WebUserControl1 ID="WebUserControl11" runat="server" OnChange="MyClick"/>
</ul>

我的 ASCX 代码 请注意,CommandArgument 用于指定单击哪个项目。此外,您可以将它用于数据库 id 或类似的值,我只使用一个简单的整数序数。

<li><asp:LinkButton ID="lb1" runat="server" OnClick="ItemChange" CommandArgument="1">item1</asp:LinkButton></li>
<li><asp:LinkButton ID="lb2" runat="server" OnClick="ItemChange" CommandArgument="2">item2</asp:LinkButton></li>
<li><asp:LinkButton ID="lb3" runat="server" OnClick="ItemChange" CommandArgument="3">item3</asp:LinkButton></li>

在 APX.CS 代码中
请注意,lblResult 是一个简单的

<asp:Label ID="lblResult" runat="server" />

我用这个只是为了展示目的

protected void MyClick(object sender, EventArgs e)
{
    int myitem = ((WebUserControl1.ItemSelectorEventArgs)e).ItemSelected;

    lblResult.Text = "You clicked Item " + myitem.ToString() + "!";
}

最后

这是我在ascx.cs 代码中创建的自定义事件参数类:

public class ItemSelectorEventArgs : EventArgs
{

    public int ItemSelected
    {
        get;
        set;
    }

    public ItemSelectorEventArgs(string indexSelected)
    {
        int tryGetANumber;

        if (int.TryParse(indexSelected, out tryGetANumber))
        {
            this.ItemSelected = tryGetANumber;
        }
        else
        {
            this.ItemSelected = -1;
        }

    }
}

记住
您在用户控件中捕获 HTML 控件的事件,从中收集一些信息,并在用户控件上触发自定义事件。

【讨论】:

【解决方案2】:
<%@ Control Language="VB" AutoEventWireup="false" CodeFile="item-lector.ascx.vb" Inherits="includes_usercontrols_item_selector" %> 
<!--Item Selector--> 
<div id="item-selector"> 
<%=Me.Output%> 
</div> 
<!-- add this code here after the </div> -->
<script type="text/javascript">
   function createFunc(i){ return function(){ alert("You clicked element " + (i + 1) + " in the list"); return false; } }   
   var els = document.getElementById('changeItemMenu').getElementsByTagName('a'); 
   for(var i = 0; i < els.length; i++) 
      els[i].onclick = createFunc(i); 
</script>

在这段代码中,我们直接应用 onclick 属性添加事件,添加事件的更好方法是使用 function like this one 或整个库,如 jQuery 或 YUI 或任何你喜欢的。

【讨论】:

  • 嗨,Marco,感谢您的快速回复。当我添加您提供的代码时,警报说我单击了列表中的元素 #23,无论我单击哪个元素。如何在后面的代码中访问该特定元素的服务器端?
  • @MHV88:我更新了代码,现在它可以工作了。这只是客户端,我不明白你的问题,你必须在服务器端做。对不起,我不知道 ASP,因为我使用 PHP,所以我无法提供任何帮助。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-09-15
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多