Mono Support WebControl - Events Not wiring up on first postback (Closed)

Viewed 33354 time(s), 9 post(s), 3/31/2012 12:39:15 PM - by shawndg
3/31/2012 12:39:15 PM
1871 Reputation 252 Total posts

Hi Guys,

I am having a hell of a time trying to figure this out..
I have a major issue that is effecting all of my web parts.

I have a main page, and then in that page i have several controls all based off off of the same code template.
If figure they are all suffering from the same event wireup problem so it I can fix one then I can fix them all.

So, to start let me explain the layout.
There is a main page aspx page.. on this page there is a web control included..
On this web control, there are a few update panels, and inside one of those panels their is a listview with a template and in its template each row item has some call back buttons to manage them.

Now, when I first load this page.. IE start up my visual studio web server and navigate to this page and then click one of these row buttons..
The call back makes it to the server, and the init is fired but the event of the button that was clicked never fires.

Now, here is where it gets weird.. click a couple more times and then it starts to fire as expected.

Code below.

<%@ Page
    Language="C#"
    AutoEventWireup="True"
    CodeBehind="/Members/Default.aspx.cs"
    Inherits="TheScene.Web.MusicProfileEditor.BandEditor"
    Theme="Scene2"
    MasterPageFile="/MonoX/MasterPages/ThePittsburghSceneHeader2.master"
%>
 
<%@ Register Assembly="AjaxControlToolkit" Namespace="AjaxControlToolkit" TagPrefix="cc1" %>
 
<%@ MasterType TypeName="MonoSoftware.MonoX.BaseMasterPage" %>  
<%@ Import Namespace="MonoSoftware.MonoX.Resources" %>
<%@ Register Assembly="MonoX" Namespace="MonoSoftware.MonoX" TagPrefix="portal" %>
<%@ OutputCache Location="None" VaryByParam="None" %>
 
<%@ Register TagPrefix="Editor" TagName="MusicEditor" Src="/Members/BandEditor/SongEditor.ascx" %>
<%@ Register TagPrefix="PE" TagName="ProfileEditor" Src="/Members/BandEditor/ProfileEditor.ascx" %>
<%@ Register TagPrefix="EM" TagName="EventEditor" Src="/Members/BandEditor/EventEditor.ascx" %>
 
<%@ Register TagPrefix="IMG" TagName="ProfileImageEditor" Src="/Members/BandEditor/ProfileImageEditor.ascx" %>
 
<asp:Content ID="Content1" ContentPlaceHolderID="cp" runat="server">
 
<link rel="stylesheet" href="../MonoX/Scripts/css/jquery.Jcrop.css" type="text/css" />
 
    <div class="page_header"><h97>Band Editor</h97></div>  
    <div class="page_box">
 
        <cc1:TabContainer ID="TabContainer1" runat="server">
       
        <cc1:TabPanel ID="TabPanel2" runat="server" HeaderText="Picture"
        <ContentTemplate
            <IMG:ProfileImageEditor runat="server" ID="ProfileImageEditor"  />
        </ContentTemplate>
 
        </cc1:TabPanel>
 
        <cc1:TabPanel ID="TabPanel3" runat="server" HeaderText="Music"
        <ContentTemplate
            <Editor:MusicEditor runat="server" ID="SongEditor"  />
        </ContentTemplate>
        </cc1:TabPanel>
         
        <cc1:TabPanel runat="server" HeaderText="Profile"
        <ContentTemplate
            <PE:ProfileEditor runat="server" ID="ProfileEditor"  />
        </ContentTemplate>
        </cc1:TabPanel>
 
         <cc1:TabPanel ID="TabPanel1" runat="server" HeaderText="Events"
        <ContentTemplate
           <EM:EventEditor runat="server" ID="EventEditor"  />
        </ContentTemplate>
        </cc1:TabPanel>
 
     
 
        </cc1:TabContainer>
</div>
 
 
</asp:Content>



<asp:UpdatePanel ID="UpdateShellPanel" runat="server" UpdateMode="Conditional">
 <ContentTemplate>
 
 <asp:UpdatePanel ID="PlaySong" runat="server" UpdateMode="Conditional">
 <ContentTemplate>
 </ContentTemplate>
 </asp:UpdatePanel>
 
 
 <!-- Start: Main Player Panel -->
 <asp:UpdatePanel ID="MainPanel" runat="server" UpdateMode="Conditional">
 <ContentTemplate>
 
 <table bgcolor="lightgreen" border="1">
    <tr>
        <th>Release Year</th>
        <th>Album Title</th>
        <th>Track #</th>
        <th>Song Title</th>
        <th>Artist</th>
        <th></th><th></th><th></th>
   
        <asp:ListView ID="ListViewSongs" runat="server"
            onitemdatabound="ListViewSongs_ItemDataBound" >
        <LayoutTemplate>
          <ul class="AlbumList">
            <asp:PlaceHolder ID="itemPlaceholder" runat="server" />
          </ul>
         </LayoutTemplate>
          
         <ItemTemplate>
           <tr>
           <td><%# Eval("ReleaseYear", "{0:d}")%></td>
           <td><%# Eval("AlbumName") %></td>
           <td><%# Eval("TrackNumber") %></td>
           <td><%# Eval("SongTitle") %></td>
           <td><%# Eval("ArtistName") %></td>
 
           <td>
               <asp:Button id="EditSong" runat="server" class="clsbtn"
               CommandArgument='<%# Eval("SongId") %>' CommandName="EditSong"  OnClick="SongBtnHandler" Text="Edit" />
           </td>
 
           <td>
 
           <asp:Button  ID="Play" runat="server" Text='Play' CommandArgument='<%# Eval("SongId") %>' />
 
 
       <%--    ClientIDMode="AutoID"     <asp:button id="Play" runat="server" class="clsbtn" UseSubmitBehavior="false"
               CommandArgument='<%# Eval("SongId") %>' CommandName="PlaySong"  OnClick="PlayerBtnHandler" Text="PLAY" />
       --%>    </td>
            
           <td>
                <asp:Button id="DeleteSong" runat="server" class="clsbtn"
                CommandArgument='<%# Eval("SongId") %>' CommandName="DeleteSong" OnClick="SongBtnHandler" Text="X" />
 
               <AJX:ConfirmButtonExtender ID="DeleteSong_ConfirmButtonExtender"
                runat="server" ConfirmText= 'Are you sure you want to delete this song ? ' Enabled="True" TargetControlID="DeleteSong">
                </AJX:ConfirmButtonExtender>
 
           </td>
 
 
           </tr>
         </ItemTemplate>
          
         <EmptyDataTemplate>
                <div>No Songs</div>
            </EmptyDataTemplate>
        </asp:ListView>
    </tr>
 
 </table>
 
 <br>
 <asp:Button ID="Uploader1Insert" runat="server" AlternateText="Upload Song" onclick="Uploader1Insert_Click" Text="Upload Song (MP3)" Width="142px" />
 
 <asp:UpdatePanel ID="UploadSongPanel" runat="server" UpdateMode="Conditional">
 <ContentTemplate>
    <asp:Label ID="Uploader1ProgressText" runat="server"></asp:Label>
    <asp:Button ID="Uploader1Cancel" runat="server" AlternateText="Cancel" Height="25px" Text="Cancel Upload" Width="139px" onclick="Uploader1Cancel_Click1" /> 
    <CuteWebUI:Uploader ID="Uploader1" runat="server" CancelButtonID="Uploader1Cancel" InsertButtonID="Uploader1Insert"
        MultipleFilesUpload="false" OnFileUploaded="Uploader_FileUploaded" ProgressCtrlID="Uploader1Progress"
        ProgressTextID="Uploader1ProgressText"><ValidateOption MaxSizeKB="10240" />
    </CuteWebUI:Uploader>
 </ContentTemplate>
 </asp:UpdatePanel>
 
 
 </ContentTemplate>
 </asp:UpdatePanel>
 
 <!-- End: Main Panel-->
 
 
 <asp:UpdatePanel ID="EditSongPanel" runat="server" Visible="False" UpdateMode="Conditional">
 <ContentTemplate>
  
<p>Artist Name:</p><p><asp:TextBox ID="txtArtistName" runat="server" Width="523px"></asp:TextBox></p>
<p>Song Title:</p><p><asp:TextBox ID="txtSongTitle" runat="server" Width="523px"></asp:TextBox></p>
<p>Album Name:</p><p><asp:TextBox ID="txtAlbumName" runat="server" Width="523px"></asp:TextBox></p>
<p>Track Number:</p><p><asp:TextBox ID="txtTrackNumber" runat="server" Width="523px"></asp:TextBox></p>
<p>Release Year:</p><p><asp:TextBox ID="txtReleaseYear" runat="server" Width="523px"></asp:TextBox></p>
 
<p>
    <%--<asp:Button ID="CancelEditCmd" runat="server" onclick="EdidCancelCmd_Click" Text="Cancel" />--%>
    <asp:Button ID="EditSaveCmd" runat="server" onclick="EditSaveCmd_Click" Text="Save" />
</p>
 
</ContentTemplate>
</asp:UpdatePanel>
 
 
</ContentTemplate>
</asp:UpdatePanel>

Code behind control..  little slimmed down but core is therem

namespace TheScene.Web.WebParts
{
    public partial class MusicEditor : BasePagedPart
    {
 
        #region Constructor
        /// <summary>
        /// Constructor.
        /// </summary>
        public MusicEditor()
        {
            Title = "Music Editor";
            IsTemplated = false;
            // ControlSpecificTemplateSubPath = "";
        }
 
        #endregion
 
        #region Page Events
 
 
        protected void Page_Init(object sender, EventArgs e)
        {
            //custom events handlers ? - was playing with this to try to solve issue.
            Page.LoadComplete += new EventHandler(Page_LoadComplete);
            ListViewSongs.ItemCommand += new EventHandler<ListViewCommandEventArgs>(ListView1_ItemCommand);
             
             
        }
 
        protected void Page_PreRender(object sender, EventArgs e)
        {
        }
 
        void Page_LoadComplete(object sender, EventArgs e)
        {
 
            if (!Page.IsPostBack)
            {
                PopulateSongList();
                MainPanel.Update();
            }
 
        }
 
        #endregion
 
        #region Methods
        /// <summary>
        /// Apply web part property changes (Note: Overridden property still needs to be marked as <see cref="MonoSoftware.MonoX.WebPartApplyChangesAttribute"/>).
        /// <para>
        /// Note: Marked with <see cref="MonoSoftware.MonoX.WebPartApplyChangesAttribute"/> attribute so it is called from ApplyChanges event in the editor part to refresh the module appearance.
        /// </para>
        /// </summary>
        ///
        [WebPartApplyChanges]
        public override void ApplyChanges()
        {
            base.ApplyChanges();
        }
 
        #endregion
 
        protected override void OnInit(EventArgs e)
        {
            base.OnInit(e);
        }
 
 
       void ListView1_ItemCommand(object sender, ListViewCommandEventArgs e)
        {
            int songid = Convert.ToInt32(e.CommandArgument.ToString());
            StreamMusic(songid);
        }


1
3/31/2012 8:02:46 PM
15993 Reputation 2214 Total posts

Hi,

first of all, when you have control structure like this best practice is to bind on the Init event, because when you do so controls will load the post data and view state properly. Although RaisePostBackEvent should raise the item command event properly as it is raised after the page load so I don't see what the event isn't fired. 

Can you please show us the rest of the code so we can check if something suspicious is there ?

Regards

2
4/1/2012 12:32:48 PM
1871 Reputation 252 Total posts

Hi Khorvat,

Ok I rewrote it and slimmed it down to reduce the amount of code that may be causing the problem..
So it is now very basic but the problem is still occurring.

When you first click play, it refreshes the page but the label does not set.
Now, click refresh in the web browser once then click again and the label sets...

Code Below..

<%@ Page
    Language="C#"
    AutoEventWireup="True"
    CodeBehind="/Members/Default.aspx.cs"
    Inherits="TheScene.Web.MusicProfileEditor.BandEditor"
    Theme="Scene2"
    MasterPageFile="/MonoX/MasterPages/ThePittsburghSceneHeader2.master"
%>
 
<%@ Register Assembly="AjaxControlToolkit" Namespace="AjaxControlToolkit" TagPrefix="cc1" %>
 
<%@ MasterType TypeName="MonoSoftware.MonoX.BaseMasterPage" %>  
<%@ Import Namespace="MonoSoftware.MonoX.Resources" %>
<%@ Register Assembly="MonoX" Namespace="MonoSoftware.MonoX" TagPrefix="portal" %>
<%@ OutputCache Location="None" VaryByParam="None" %>
 
<%@ Register TagPrefix="Editor" TagName="MusicEditor" Src="/Members/BandEditor/SongEditor.ascx" %>
 
<asp:Content ID="Content1" ContentPlaceHolderID="cp" runat="server">
 
    <div class="page_header"><h97>Band Editor</h97></div>  
    <div class="page_box">
 
          <Editor:MusicEditor runat="server" ID="SongEditor"  />
 
</div>
</asp:Content>

<%@ Control Language="C#" AutoEventWireup="True" CodeBehind="SongEditor.ascx.cs" Inherits="TheScene.Web.WebParts.MusicEditor" %>
<%@ Register Namespace="MonoSoftware.Web.Pager" Assembly="MonoSoftware.Web.Pager" TagPrefix="mono" %>
<%@ Register Assembly="CuteWebUI.AjaxUploader" Namespace="CuteWebUI" TagPrefix="CuteWebUI" %>
<%@ Register Assembly="AjaxControlToolkit" Namespace="AjaxControlToolkit" TagPrefix="AJX" %>
 
 <asp:UpdatePanel ID="UpdateShellPanel" runat="server" UpdateMode="Conditional">
 <ContentTemplate>
 
 <asp:UpdatePanel ID="PlaySong" runat="server" UpdateMode="Conditional">
 <ContentTemplate>
 <asp:Label ID="test" runat="server" Text="notset" />
 </ContentTemplate>
 </asp:UpdatePanel>
 
 <!-- Start: Main Player Panel -->
 <asp:UpdatePanel ID="MainPanel" runat="server" UpdateMode="Conditional" ChildrenAsTriggers="true">
 <ContentTemplate>
 
 <table bgcolor="lightgreen" border="1">
    <tr>
        <th>Song Title</th>
        <th></th>
   
        <asp:ListView ID="ListViewSongs" runat="server"
            onitemdatabound="ListViewSongs_ItemDataBound" >
        <LayoutTemplate>
          <ul class="AlbumList">
            <asp:PlaceHolder ID="itemPlaceholder" runat="server" />
          </ul>
         </LayoutTemplate>
          
         <ItemTemplate>
           <tr>
           <td><%# Eval("SongTitle") %></td>
           <td>
           <asp:button id="Play" runat="server" class="clsbtn" UseSubmitBehavior="false"
               CommandArgument='<%# Eval("SongId") %>' CommandName="PlaySong"  OnClick="PlayerBtnHandler" Text="PLAY" />
           </td>
           </tr>
         </ItemTemplate>
          
         <EmptyDataTemplate>
                <div>No Songs</div>
            </EmptyDataTemplate>
        </asp:ListView>
    </tr>
 
 </table>
 
 </ContentTemplate>
 </asp:UpdatePanel>
 
 <!-- End: Main Panel-->
 
 </ContentTemplate>
</asp:UpdatePanel>
 <!-- End: SHELL Panel-->

using System;
using MonoSoftware.MonoX.ModuleGallery;
using System.Web.UI.WebControls;
using System.ComponentModel;
using System.Web.Security;
using MonoSoftware.MonoX;
using MonoSoftware.Web;
using MonoSoftware.MonoX.Utilities;
using System.IO;
using System.Configuration;
using System.Linq.Expressions;
using System.Linq;
using System.Web;
using System.Text;
 
//Song Function
using TheScene.DataManager.Songs;
 
namespace TheScene.Web.WebParts
{
    public partial class MusicEditor : BasePagedPart
    {
 
 
        public string MyMediaPath = ConfigurationManager.AppSettings["SceneMediaPath"];
        public string MyMediaStramerUrl = ConfigurationManager.AppSettings["SceneStreamerUrl"];
 
        #region Constructor
        /// <summary>
        /// Constructor.
        /// </summary>
        public MusicEditor()
        {
            Title = "Music Editor";
            IsTemplated = false;
            // ControlSpecificTemplateSubPath = "";
        }
 
        #endregion
 
        #region Page Events
 
        protected void Page_Load(object sender, EventArgs e)
        {
 
            string test = Request.Form["__EVENTTARGET"];
 
            System.Diagnostics.Debug.WriteLine(test);
 
        }
 
 
        protected void Page_Init(object sender, EventArgs e)
        {
            //custom events handlers ?
            Page.LoadComplete += new EventHandler(Page_LoadComplete);
            ListViewSongs.ItemCommand += new EventHandler<ListViewCommandEventArgs>(PlayerBtnHandler);
 
        }
 
        protected void Page_PreRender(object sender, EventArgs e)
        {
        }
 
        void Page_LoadComplete(object sender, EventArgs e)
        {
 
            if (!Page.IsPostBack)
            {
                PopulateSongList();
                MainPanel.Update();
            }
 
        }
 
        #endregion
 
        #region Methods
        /// <summary>
        /// Apply web part property changes (Note: Overridden property still needs to be marked as <see cref="MonoSoftware.MonoX.WebPartApplyChangesAttribute"/>).
        /// <para>
        /// Note: Marked with <see cref="MonoSoftware.MonoX.WebPartApplyChangesAttribute"/> attribute so it is called from ApplyChanges event in the editor part to refresh the module appearance.
        /// </para>
        /// </summary>
        ///
        [WebPartApplyChanges]
        public override void ApplyChanges()
        {
            base.ApplyChanges();
        }
 
        #endregion
 
        protected override void OnInit(EventArgs e)
        {
            base.OnInit(e);
        }
 
 
        #region Player Functions
 
        protected void PopulateSongList()
        {
            SongManager MySongManager = new SongManager();
            MySongManager.ConnectionString = MonoSoftware.MonoX.ApplicationSettings.LocalSqlServer;
            ListViewSongs.DataSource = MySongManager.GetMusicList(GetMyGuid());
            ListViewSongs.DataBind();
        }
 
 
        protected void PlayerBtnHandler(Object sender, EventArgs e)
        {
            Button btn = (Button)sender;
            int songid = Convert.ToInt32(btn.CommandArgument.ToString());
 
            switch (btn.CommandName)
            {
                case "PlaySong":
                    StreamMusic(songid);
                    break;
            }
        }
 
 
        protected void StreamMusic(int songid)
        {
 
            test.Text = "fired!";
 
            PopulateSongList();
            PlaySong.Update();
 
        }
 
 
        #endregion
 
        #region Common
 
        public Guid GetMyGuid()
        {
            Guid MyGuid = Guid.Empty;
            MyGuid = new Guid("12BBECE2-CD35-4B71-81BA-9F8301211538");
            //MyGuid = SecurityUtility.GetUserId();
            return MyGuid;
        }
 
        public static bool IsDate(Object obj)
        {
            string strDate = obj.ToString();
            try
            {
                DateTime dt = DateTime.Parse(strDate);
                if (dt != DateTime.MinValue && dt != DateTime.MaxValue)
                    return true;
                return false;
            }
            catch
            {
                return false;
            }
        }
 
 
        public bool IsStringNumber(string numberstr)
        {
            numberstr = numberstr.Trim();
            double Num;
            bool isNum = double.TryParse(numberstr, out Num);
            return isNum;
        }
 
        #endregion
 
        protected void ListViewSongs_ItemDataBound(object sender, ListViewItemEventArgs e)
        {
            //Button button = e.Item.FindControl("Play") as Button;
 
            //if (button != null)
            //{
            //    AjaxControlToolkit.ToolkitScriptManager.GetCurrent(Page).RegisterAsyncPostBackControl(button);
            //}
 
        }
 
    }
}




3
4/2/2012 10:58:08 PM
1871 Reputation 252 Total posts

tried evrything I can think of. only thing I found is problem has something to do with the listview. controls outside of it work fine on first post back. I even removed the update panels but same problem on listview post back.

4
4/3/2012 10:48:07 AM
15993 Reputation 2214 Total posts

Hi,

can you please try to call the PopulateSongList(); on the OnInit event and see if that helps. Get back to me with the results.

Regards

5
4/4/2012 11:43:53 AM
1871 Reputation 252 Total posts

Hi Khorvat,

Yes that did make it work!..

But It seems that I have to call it each and every time the page loads.
I tried using if !page.postback but then it did not work right..

Now, I figured ok thats not so bad then It will just bind each time there is a page load because I am binding data inside that function and calling it on page init on the control each time... But.. even though page init is called on any type of postback my binding fires.. it alone is not enough for the binding to update.
So, on top of binding on Page.Init I also have to rebind after any database operation which is a little strange considering it would in theory be binding twice..

But this work around does seem to work..
I dug a little more and even found a known bug with the Microsoft ListView Control unable to determine its clientId under certain situations..

Over all this solution works, I am just worried that it is poor coding on my behalf because something keeps telling me I am binding more then I should need too.

Any thoughts ?

6
4/6/2012 7:47:50 AM
15993 Reputation 2214 Total posts

Hi,

when you have nested controls and you want ASP.NET to load it's state you need to do early binding and rebind later if needed, because control that should raise the postback / callback isn't created and you need to create it very early so everything can properly work. As for Microsoft ListView, most of MonoX WebParts are using it and we didn't find any problems with it.

So it isn't that bad to bind the control twice if control result is paged and everything else is optimized, today's Web servers will handle it be sure of that ;)

Regards

7
4/6/2012 7:48:49 AM
15993 Reputation 2214 Total posts

Also let me know if we can consider this topic as solved and if we can close it  ?

8
4/9/2012 8:14:07 PM
1871 Reputation 252 Total posts

Yep.
Need to make sure to bind on init for anything that has a listview..

And bind on each page load...
No ispostback.. checking..

9
This is a demo site for MonoX. Please visit Mono Software for more info.