【问题标题】:Fire up event from Image Button in a User Control inside a Data List从数据列表内的用户控件中的图像按钮触发事件
【发布时间】:2011-07-13 15:43:41
【问题描述】:

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

我需要捕捉任何被触发以执行某些操作的按钮(因此我需要识别它)。该按钮位于由“DataList”包含的用户控件内,该用户控件位于用户控件内,该控件是从页面(也具有母版页)加载的。你可以在这里看到嵌套顺序:Page->User-Control->DataList->User Control->ImageButton

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

Members.aspx

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

Members.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”控件中分配给图像按钮“CommandName”,这是单击按钮时我需要检索的值。事实上,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" />

Event.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

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”并且事件被捕获没有问题。 如果有人能帮助我解开这个烂摊子,我会很高兴。

提前谢谢你,

哈维尔

【问题讨论】:

    标签: c# asp.net datalist webformsmvp


    【解决方案1】:

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

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

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

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

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

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

    【讨论】:

    • 您好:感谢您的回答。让我尽可能地解释清楚
    【解决方案2】:

    感谢您的回答。让我尽可能地解释清楚

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

    是的,“CommandName”是在后面的代码中设置的。我将一个对象传递给“ContactImage”用户控件,其中包含属性(一个 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();
        }
    
    
    }
    

    在 PostBack 期间数据列表未绑定,应用程序无法尝试“绘制”其中的控件,所以我不知道这里是否捕获了事件。我试图将数据绑定移动到其他页面生命周期(Init、Binding、PreLoad、...),但奇怪的是,List 还没有数据。 Presenter 在主页面 Init 上被调用,但在页面加载之前没有数据传递给控制(并且 Control:Init 已经完成)。

    我刚刚做了一个技巧,添加了两次数据绑定(控件的 Page Init 和 Load ),并且在 PostBack 期间,当控件绘制时没有数据(因此没有错误输出)时,事件永远不会到达“ItemCommand”,它似乎是丢了。

    在我看来,所有这些都是页面生命周期(控件更复杂)和在​​ PostBack 处理过程中触发的事件的问题。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2016-08-30
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多