开发者

Fire up event from Image Button in a User Control inside a Data List

:

This is my first post here, so I beg you forgive my mistkaes :D The problem I'm facing is the following: I'm trying to catch event from some 'ImageButton' inside a Data List but I am experiencing some problems.

I need like to catch any button that is fired up to do some action (so I need to identify it). The button is inside an User Control that is contained by 'DataList', that is placed inside a User Control, that is load from a Page (that has a Master Page also). You can see the nested order here : Page->User-Control->DataList->User Control->ImageButton

I have to say web application is built using Web Forms MVP pattern so Pages (not controls) have a Presenter that manages all the logic and send data to bind web forms, that load the needed controls.

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.R开发者_运维问答esolve<IMembersPresenter>();

        _presenter.Init(this, IsPostBack);

    }
......
    public void ShowFriendPanel(IList<ContactInfo> friendList)
    {
        DataBoxControl.FriendsList = friendList.ToList();
    }

Presenter looks like this:

    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);

        }

And the control DataBoxControl contains a Data List that contains another User Control

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

And final User Control (ContactImage.ascx) contains Web Control 'ImageButton'

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

Id to do action is assigned in 'ContactImage' Control to Image Button 'CommandName' and that's the value I need to retrieve when button is clicked. In fact, ContactImage User Control doesn't do anything inside and I rely the fired event to OnItemCommand on the Data List but I have two problems:

  1. I cannot bind the Data List before Page_Load so I have to check data binding is taking place when 'IsPostBack' is false; in that case, the fired event doesn't take place because the ContactImage fails trying to fullfil its properties (DataList Item is empty because List is not binding).
  2. If Data List binding is moved to Page_Init (in the User Control) the event is fired up but OnItemCommand doesn't receive anything at all (and List to bind Data List is empty also).

I wonder if the pattern I'm using is responsible in some way because I built a simple website and it works and event reaches ItemCommand

Simple Website (here it works but no MVP pattern is used) 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

<%@ 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;
    }
}

In others pages, I'm using delegates to handle events, but there no 'DataList' is used and the event is catched without problems. I would be so glad if anyone could help me in anyway to untangle this mess.

Thank you in advance,

Javier


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.


Thank for your answer. Let me explain as much better as I can

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.

Yes, the 'CommandName' is set on the code behind. I pass an object to 'ContactImage' User Control and that contains the property (an ID). I checked it while debugging and took the correct value.

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.

Yes, I really have access to that button and it has the needed data, even I could add some logic inside the control but, to keep the software design (Web Form MVP pattern) I need to raise the event up, to Presenter and that's the mission I'm involved in :)

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.

That was I tried first, using event delegation but it seemed not to work. Maybe I need to recheck my code before anything but I read that Data List is able to catch all fired events inside it so I go for the shortest way to reduce the amount of code and extracting any logic from User Controls.

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.

Oh, I would like to do that. In the sample website I built (latest code on my post) everything works right but in real app I need to keep 'ContactImage' control as it is because it is being used by others controls and pages, and that's why it is a User Control.

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.

Sorry to hear that; it's my fault. The main problem is: I'm not being able to get the event when Image Button is clicked (within a control that is inside a Data List in parent control) and pass the argument to the Presenter.

An issue I have seen is I get an error when button is clicked if Data List is bound within Page Load, without check is 'PostBack' is false (I cannot post images yet, sorry)

In case I check this one first:

DataBoxControl.ascx.cs

........

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


}

the Data List is not bound during PostBack and the application fails trying to 'draw' the controls inside it, so I don't know here whether event is caught or not. I tried to move data binding to other Page Life Cycle (Init, Binding, PreLoad,...) but, oddly, List has no data yet. Presenter is called on main Page Init but no data is passed to control until Page Load (and Control:Init has done then).

I just made a trick adding data binding twice (both control's Page Init & Load ) and during PostBack, while the control was drawn without data (so no error output) the event never gets to 'ItemCommand' and it seems to be lost.

All that stuff, seems to me, a problem with Page Life Cycle (more complicated with controls) and events that are being fired up while PostBack is taken process.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜