这是我在这里的第一篇文章,所以我求求你原谅我的错误: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,但我有两个问题:
我想知道我使用的模式是否以某种方式负责,因为我构建了一个简单的网站,它的工作原理和事件达到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> </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'并且事件被捕获而没有问题。 如果有人能帮我解决这个烂摊子,我会很高兴。
提前谢谢你,
哈维尔
答案 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进行过程中被激活的事件的问题。