从数据列表内用户控件中的图像按钮启动事件

本文关键字:图像 按钮 启动 事件 控件 数据 列表 用户 | 更新日期: 2023-09-27 18:01:54

这是我在这里的第一篇文章,所以我恳求你原谅我的迷雾:D我面临的问题如下:我正在尝试从数据列表中的某个"ImageButton"捕获事件,但我遇到了一些问题。

我需要抓住任何触发的按钮来执行一些操作(所以我需要识别它(。该按钮位于由"DataList"包含的用户控件内,该控件放置在用户控件内,该控件从页面加载(也具有母版页(。您可以在此处看到嵌套顺序:Page->User-Control->DataList->User Control->ImageButton

我不得不说 Web 应用程序是使用 Web 窗体 MVP 模式构建的,因此页面(不是控件(有一个演示器来管理所有逻辑并发送数据以绑定 Web 表单,从而加载所需的控件。

成员.aspx

.......
<%@ Register Src="~/Controls/DataControl.ascx" TagName="DataBox" TagPrefix="dtC" %>
.......
<dtC:DataBox ID="DataBoxControl" runat="server" />

成员.aspx.cs

    protected void Page_Load(object sender, EventArgs e)
    {
        _presenter = IoCFactory.Instance.CurrentContainer.Resolve<IMembersPresenter>();
        _presenter.Init(this, IsPostBack);
    }
......
    public void ShowFriendPanel(IList<ContactInfo> friendList)
    {
        DataBoxControl.FriendsList = friendList.ToList();
    }

演示者如下所示:

    public override void Init(IMemberView view, bool isPostBack)
    {
        base.Init(view,isPostBack);//authentication and basic stuff

        IList<ContactInfo> friendContactList = _userAccountDao.GetFriendsOfUser(CurrentUser.Id, 0, int.MaxValue);

        if ((friendContactList.Count > 0))
        {
            ShowFriendsBox(friendContactList);
        }

控件 DataBoxControl 包含一个包含另一个用户控件的数据列表

  <asp:DataList ID="dataDL" runat="server" OnItemDataBound="dataDL_ItemDataBound" OnItemCommand="dataDL_ItemCommand"   >
        <ItemTemplate>
             <ci1:ContactImage runat="server" ID="ContactImageControl" Height="59px" Width="59"  Show="All" />
        </ItemTemplate>
  </asp:DataList>

最终用户控件 (ContactImage.ascx( 包含 Web 控件"ImageButton">

 ......
 <asp:ImageButton ID="deleteButton" ImageUrl="/images/remove_contact_icon.png" runat="server"  />
  .......

"联系人图像"控件中将要执行的操作的 id 分配给图像按钮"命令名称",这是我在单击按钮时需要检索的值。事实上,ContactImage 用户控件在内部不做任何事情,我将触发的事件依赖于数据列表上的 OnItemCommand,但我有两个问题:

  1. 我无法在Page_Load之前绑定数据列表,因此我必须检查当"IsPostBack"为假时是否进行了数据绑定;在这种情况下,触发的事件不会发生,因为 ContactImage 尝试完成其属性失败(DataList Item 为空,因为 List 未绑定(。
  2. 如果将数据列表绑定移动到Page_Init(在用户控件中(,则会触发事件,但 OnItemCommand 根本不接收任何内容(并且要绑定的数据列表的列表也为空(。

想知道我使用的模式是否以某种方式负责,因为我构建了一个简单的网站并且它可以工作并且事件到达 ItemCommand

简单网站(这里它有效,但没有使用 MVP 模式(事件.aspx

 <h2>
    Events
</h2>
<p>
    Events into Data List
</p>
<asp:DataList ID="DataListWihtEvents" RepeatDirection="Horizontal" RepeatColumns="4" OnItemCommand="DataList_ItemCommand" runat="server">
    <ItemTemplate>
        <tnc:TopControl ID="TopControlNested" runat="server" Number="<%# (Container.DataItem) %>" />
    </ItemTemplate>
    <SeparatorTemplate>&nbsp;</SeparatorTemplate>
</asp:DataList>
<br />
<asp:Label ID="ShowButtonFiredUpTitle" runat="server" Text="Here goes the button that was fired up: " />
<asp:Label ID="ShowButtonFiredUp" runat="server" Font-Bold="True" />

事件.aspx.cs

public partial class Events : System.Web.UI.Page
{
    protected List<int> Numbers = new List<int>();
    protected void Page_Init(object sender, EventArgs e)
    {
        for (int i = 1; i < 5; i++)
        {
            Numbers.Add(i);
        }
        DataListWihtEvents.DataSource = Numbers;
        DataListWihtEvents.DataBind();
    }
    protected void DataList_ItemCommand(object source, DataListCommandEventArgs e)
    {
        if (e.CommandSource.GetType() == typeof(Button))
        {
            var b = (Button) e.CommandSource;
            ShowButtonFiredUp.Text = b.CommandName;
        }
    }

TopNestedControl.ascx

<%@ Register src="~/controls/BottomNestedControl.ascx" TagName="BottomControl" TagPrefix="bnc" %>

TopNestedControl.ascx.cs

public partial class TopNestedControl : System.Web.UI.UserControl
{
    public int Number { get; set; }
    protected void Page_Load(object sender, EventArgs e)
    {
        BottomNestedControl.Number2 = Number;
    }
}

BottomNestedControl.ascx

<asp:Button ID="ShowNumberButton" runat="server" Text="Button" CommandName="button fired up!" />

BottomNestedControl.ascx.cs

public partial class BottomNestedControl : System.Web.UI.UserControl
{
    public int Number2 { get; set; }
    protected void Page_Load(object sender, EventArgs e)
    {
        ShowNumberButton.Text = "Button " + Number2;
        ShowNumberButton.CommandName = "#" + Number2;
    }
}

在其他页面中,我使用委托来处理事件,但没有使用"DataList",并且捕获事件没有问题。如果有人能帮助我解开这个烂摊子,我会很高兴。

提前谢谢你,

哈维尔

从数据列表内用户控件中的图像按钮启动事件

当存在太多层时,页面的生命周期起着非常重要的作用。 我没有详细说明应该在哪个周期上执行哪些操作(谷歌做得更好(,我只是要列出一些提示和技巧。

让页面呈现,使用 IE 或 Chrome 或 Firebugs(对于 Firefox(,然后按 f12。选择有问题的按钮之一,然后查看是否正确设置了 CommandName 属性。从上面的代码中,该属性从未设置过,因此我假设您在隐藏的代码上执行此操作。

  • 如果您有权访问按钮(回发源(,则只需将其他属性绑定到按钮上并使用该信息。

  • 如果 CommandName 和 OnItemCommand 已正确设置,但仍未捕获事件,则始终可以将自定义事件附加到按钮并引发它。

  • 在 ID="dataDL" 对象上,删除自定义控件并放入一个简单的带有静态命令名称的 asp:button,然后在调试模式下运行它,看看它是否触发了dataDL_ItemCommand。 我觉得事件没有触发很奇怪。

现在,从您的帖子中不清楚您遇到的问题类型。 您应该限制它,以便更容易提出解决方案。

谢谢你的回答。让我尽可能好地解释

让页面呈现,使用 IE 或 Chrome 或 Firebugs(对于 Firefox(,然后按 f12。选择有问题的按钮之一,然后查看是否正确设置了 CommandName 属性。从上面的代码中,该属性从未设置过,因此我假设您在隐藏的代码上执行此操作。

是的,"命令名称"是在隐藏的代码上设置的。我将一个对象传递给"联系人图像"用户控件,其中包含属性(ID(。我在调试时检查了它并取了正确的值。

如果您有权访问按钮(回发源(,则只需将其他属性绑定到按钮上并使用该信息。

是的,我确实可以访问该按钮,并且它具有所需的数据,甚至可以在控件中添加一些逻辑,但是,为了保持软件设计(Web 表单 MVP 模式(,我需要将事件提升到演示者,这就是我参与的任务:)

如果 CommandName 和 OnItemCommand 已正确设置,但仍未捕获事件,则始终可以将自定义事件附加到按钮并引发它。

这是我首先尝试使用事件委派,但它似乎不起作用。也许我需要在任何事情之前重新检查我的代码,但我读到数据列表能够捕获其中所有触发的事件,所以我选择了最短的方法来减少代码量并从用户控件中提取任何逻辑。

在 ID="dataDL" 对象上,删除自定义控件并放入一个简单的带有静态命令名称的 asp:button,然后在调试模式下运行它,看看它是否触发了dataDL_ItemCommand。我觉得事件没有触发很奇怪。

哦,我想这样做。在我构建的示例网站(我帖子中的最新代码(中,一切正常,但在实际应用程序中,我需要保持"ContactImage"控件,因为它被其他控件和页面使用,这就是为什么它是一个用户控件。

现在,从您的帖子中不清楚您遇到的问题类型。您应该限制它,以便更容易提出解决方案。

很抱歉听到这个消息;这是我的错。主要问题是:当单击图像按钮(在父控件的数据列表内的控件内(并将参数传递给演示器时,我无法获取事件。

我看到的一个问题是,如果数据列表绑定在页面加载中,则单击按钮时出现错误,未经检查是"回发"是假的(我还不能发布图像,对不起(

如果我先检查一下:

DataBoxControl.ascx.cs

........
public WhatEverType WhatEverData
{
    get;
    set;
}
protected void Page_Init(object sender, EventArgs e)
{
    if (!IsPostBack)
    {
        DataListWihtEvents.DataSource = WhatEverData;
        DataListWihtEvents.DataBind();
    }

}

数据列表在回发期间未绑定,应用程序尝试"绘制"其中的控件失败,因此我不知道此处是否捕获了事件。我尝试将数据绑定移动到其他页面生命周期(初始化,绑定,预加载,...(,但奇怪的是,List还没有数据。演示器在主页初始化时被调用,但在页面加载之前不会将数据传递给控件(并且 Control:Init 已经完成(。

我刚刚做了一个技巧,两次添加数据绑定(控件的页面初始化和加载(和在回发期间,当控件是在没有数据的情况下绘制的(因此没有错误输出(时,事件永远不会到达"ItemCommand",它似乎丢失了。

在我看来,所有这些东西都是页面生命周期的问题(控件更复杂(以及在回发过程中触发的事件。