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

时间:2011-07-13 15:43:41

标签: c# asp.net datalist webformsmvp

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

我需要抓住任何被激活的按钮来执行某些操作(所以我需要识别它)。该按钮位于由“DataList”包含的用户控件内,该用户控件位于用户控件内,该用户控件从页面加载(也具有母版页)。您可以在此处查看嵌套订单:Page-> User-Control-> DataList-> User Control-> ImageButton

我不得不说Web应用程序是使用Web Forms MVP模式构建的,因此Pages(不是控件)有一个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();
    }

Presenter看起来像这样:

    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 Control'ImageButton'

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

要执行操作的ID在“ContactImage”控件到图像按钮“CommandName”中分配,这是我在单击按钮时需要检索的值。实际上,ContactImage用户控件在内部没有做任何事情,我将触发事件依赖于数据列表上的OnItemCommand,但我有两个问题:

  1. 我无法在Page_Load之前绑定数据列表,因此当'IsPostBack'为false时,我必须检查数据绑定是否正在发生;在这种情况下,触发事件不会发生,因为ContactImage尝试完全填充其属性失败(DataList Item为空,因为List没有绑定)。
  2. 如果将数据列表绑定移动到Page_Init(在用户控件中),则会触发事件,但OnItemCommand根本不会收到任何内容(并且绑定数据列表的列表也为空)。
  3. 我想知道我使用的模式是否以某种方式负责,因为我构建了一个简单的网站,它的工作原理和事件达到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" />
    

    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

    &lt;%@ Register Src =“〜/ Controls / BottomNestedControl.ascx”TagName =“BottomControl”TagPrefix =“bnc”%&gt;

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

    提前谢谢你,

    哈维尔

2 个答案:

答案 0 :(得分:0)

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

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

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

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

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

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

答案 1 :(得分:0)

感谢您的回答。让我尽可能地解释一下

  

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

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

  

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

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

  

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

那是我首先尝试使用事件委托,但似乎没有用。也许我需要在任何事情之前重新检查我的代码,但我读到数据列表能够捕获其中的所有被激活的事件,所以我采用最短的方式来减少代码量并从用户控件中提取任何逻辑。

  

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

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

  

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

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

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

如果我先检查一下这个:

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还没有数据。在主页面Init上调用Presenter,但在页面加载(和Control:Init完成)之前,没有数据传递给控件。

我只是添加了两次数据绑定(控件的Page Init&amp; Load)和PostBack期间的技巧,而控件是在没有数据的情况下绘制的(所以没有错误输出)事件永远不会到达'ItemCommand'而且似乎迷路了。

在我看来,所有这些内容都是Page Life Cycle(更复杂的控件)和在PostBack进行过程中被激活的事件的问题。