0

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

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

我不得不说 Web 应用程序是使用 Web Forms MVP 模式构建的,因此 Pages(不是控件)有一个 Presenter 来管理所有逻辑并发送数据以绑定 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 to do action 在“ContactImage”控件中分配给图像按钮“CommandName”,这是单击按钮时我需要检索的值。实际上,ContactImage 用户控件在内部没有做任何事情,我将触发的事件依赖于数据列表上的 OnItemCommand,但我有两个问题:

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

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

简单的网站(在这里它可以工作,但没有使用 MVP 模式) Event.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;
    }
}

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

先感谢您,

哈维尔

4

2 回答 2

0

When too many layers exist, the page's life cycle plays a really important role. Instead of going into detail on which actions should be done on which cycle (google does a better job), I'm just going to lay out some tips and tricks instead.

Let the page render, use IE or Chrome or Firebugs (for Firefox) and press f12. Select one of the buttons in question and see if the CommandName attribute is correctly set. From your code above, that property was never set, so I assumed you did it on the code behind.

  • If you have access to the button (source of the post back), you can just bind other attributes onto the button and use that information.

  • If the CommandName and OnItemCommand is properly set up, but the event is still not being caught, you can always attach a custom event to the button and raise it.

  • On your ID="dataDL" object, remove the custom control and put in a simple asp:button with a static command name, then run it in debug mode and see if it even triggers dataDL_ItemCommand. I find it weird that the event is not firing.

Right now, it isn't clear from your post, what type of problem you are having. You should limit it down so it is easier to propose a solution.

于 2011-07-13T18:32:28.393 回答
0

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

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

是的,“CommandName”是在后面的代码中设置的。我将一个对象传递给“ContactImage”用户控件,其中包含属性(一个 ID)。我在调试时检查了它并取了正确的值。

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

是的,我确实可以访问该按钮并且它具有所需的数据,即使我可以在控件内添加一些逻辑但是,为了保持软件设计(Web 表单 MVP 模式),我需要向 Presenter 提出事件,这就是我参与的任务:)

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

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

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

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

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

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

我看到的一个问题是,如果在页面加载中绑定了数据列表,则单击按钮时出现错误,没有检查“回发”是否为假(我还不能发布图像,抱歉)

如果我先检查这个:

数据框控件.ascx.cs

........

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


}

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

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

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

于 2011-07-13T23:14:00.533 回答