Home | Contact Us | FAQ | Search & Site Map | Link to Us
Sign In | Join | Other 45 Sites in Network
HomeAnnouncementsFree MagazinesWhite PapersSubmit Content
Discussion GroupsASP.NETWindows FormsLanguages.NET FrameworkVisual Studio.NET
Articles.NET FrameworkASP.NETToolsWindows Forms
.NET DirectoryOpen Source ProjectsUser GroupsWeb Resources
Related Topics
Visual Basic 6SQL ServerMS AccessOther DB ProductsMS Server ProductsMore Topics ...

.NET Forum / ASP.NET / Building Controls / August 2006

Tip: Looking for answers? Try searching our database.

IPostBackDataHandler not working properly with DataGrid

Thread view: 
Enable EMail Alerts  Start New Thread
Thread rating: 
buzlite@sympatico.ca - 11 Aug 2006 23:50 GMT
Hello All,

I've posted this in
microsoft.public.dotnet.framework.aspnet.datagridcontrol but got not
reply so I'll try my luck here.

Any help would be greatly appreciated.
Thanks

I am having some difficulties with a user control implementing
IPostBackDataHandler when it is placed inside a datagrid.

I have created a user control (MyUserControl.ascx) containing 1 TextBox
that implements the IPostBackDataHandler.
I have also created a form (WebForm1.aspx) that contains 1 datagrid of
which the datagrid contains the above user control as specified in its
template.

The purpose is to dynamically create one MyUserControl for each item in
the datasource for display and editing.

When the program is run and text is entered into MyUserControl's
textbox, the LoadPostData() of MyUserControl.ascx is called as
expected.  But even though LoadPostData() returns true the
corresponding RaisePostDataChangedEvent() is not called.

Note: if I were to simply include the MyUserControl.ascx in
WebForm1.aspx, then both LoadPostData() and RaisePostDataChangedEvent()
of MyUserControl.ascx are called as expected.

Would someone give me some insight as to why this is not working ?  Am
I missing a step somewhere ?

Attached is the bare essential code snippets to reproduce the problem.

MyUserControl.ascx
-----------------------------------------------------
<%@ Control Language="c#" AutoEventWireup="false"
Codebehind="MyUserControl.ascx.cs" Inherits="test.MyUserControl"
TargetSchema="http://schemas.microsoft.com/intellisense/ie5"%>
<asp:TextBox id="TextBox1" runat="server"></asp:TextBox>

MyUserControl.ascx.cs
-----------------------------------------------------
public class MyUserControl : System.Web.UI.UserControl,
IPostBackDataHandler, INamingContainer
{
protected System.Web.UI.WebControls.TextBox TextBox1;

#region Web Form Designer generated code
override protected void OnInit(EventArgs e)
{
//
// CODEGEN: This call is required by the ASP.NET Web Form Designer.
//
InitializeComponent();
base.OnInit(e);

if (Page != null)
{
Page.RegisterRequiresPostBack(this);
}
}

/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent()
{
this.Load += new System.EventHandler(this.Page_Load);

}
#endregion

public virtual bool LoadPostData(string postDataKey,
System.Collections.Specialized.NameValueCollection postCollection)
{
return true;
}

public virtual void RaisePostDataChangedEvent()
{
}

private void Page_Load(object sender, System.EventArgs e)
{
}
}

WebForm1.aspx
------------------------------------------------------
<%@ Register TagPrefix="f4c" TagName="MyUserControl"
Src="MyUserControl.ascx" %>
<%@ Page language="c#" Codebehind="WebForm1.aspx.cs"
AutoEventWireup="false" Inherits="test.WebForm1" %>
...
<form id="Form1" method="post" runat="server">
<asp:datagrid id="dgListing" runat="server"
AutoGenerateColumns="False">
<Columns>
<asp:TemplateColumn>
<ItemTemplate>
<f4c:MyUserControl id="MyUserControl1"
runat="server"></f4c:MyUserControl>
</ItemTemplate>
</asp:TemplateColumn>
</Columns>
</asp:datagrid>
<asp:Button id="Button1" runat="server" Text="Button"></asp:Button>
</form>

WebForm1.aspx.cs
------------------------------------------------------
public class WebForm1 : System.Web.UI.Page
{

...
private void Page_Load(object sender, System.EventArgs e)
{
//setup handlers
this.Button1.Click += new System.EventHandler(this.Button1_Click);

//setup datagrid
dgListing.DataSource = this.CreateDataSource();
dgListing.DataBind();
}

private void Button1_Click(object sender, System.EventArgs e)
{
}

ICollection CreateDataSource()
{
DataTable dt = new DataTable();
DataRow dr;

dt.Columns.Add(new DataColumn("SomeColumn", typeof(Int32)));

for (int i = 0; i < 2; i++)
{
dr = dt.NewRow();
dr[0] = i;
dt.Rows.Add(dr);
}

DataView dv = new DataView(dt);
return dv;
}
}
Gaurav Vaish (www.EduJini.IN) - 12 Aug 2006 04:28 GMT
> The purpose is to dynamically create one MyUserControl for each item in
> the datasource for display and editing.

How and where are you adding it?

The best place is CreateChildControls() method.

Signature

Happy Hacking,
Gaurav Vaish | http://www.mastergaurav.org
http://www.edujini.in | http://webservices.edujini.in
-------------------

buzlite@sympatico.ca - 12 Aug 2006 14:55 GMT
The user control is added inside the WebForm1.aspx file inside the
column template of the datagrid control

Thanks

> > The purpose is to dynamically create one MyUserControl for each item in
> > the datasource for display and editing.
[quoted text clipped - 8 lines]
> http://www.edujini.in | http://webservices.edujini.in
> -------------------
buzlite@sympatico.ca - 14 Aug 2006 15:55 GMT
Hello All,
Any help would be appreciated.
Thanks

> Hello All,
>
[quoted text clipped - 146 lines]
> }
> }
Gaurav Vaish (www.EduJini.IN) - 14 Aug 2006 17:30 GMT
Hi,

The only missing thing that will need to fill, as I think, is a simple
hidden field... so that it can be captured in LoadPostData.

btw, what happens if you blindly return 'true' in LoadPostData?

Signature

Happy Hacking,
Gaurav Vaish | http://www.mastergaurav.org
http://www.edujini.in | http://webservices.edujini.in
-------------------

> Hello All,
> Any help would be appreciated.
[quoted text clipped - 150 lines]
>> }
>> }
buzlite@sympatico.ca - 14 Aug 2006 22:46 GMT
Hello Gaurav,

I do not know the reasoning for adding a hidden field and what purpose
that would accomplish.

>From the sample code attachments, when WebForm1.aspx is run and the
Datagrid generates MyUserControl user control, any text that is entered
in this user control TextBox would be properly posted back to the
server.  This is true in that when MyUserControl.ascx.cs,
LoadPostData() is called, the data can be retrieved from the input
parameter of this method.  So...this is working OK.

The problem is, when MyUserControl.ascx.cs, LoadPostData() returns a
value of 'true', RaisePostDataChangedEvent() is never invoked.  In the
MyUserControl.ascx.cs code snippet, I hardcoded a return of 'true'.
Even then, RaisePostDataChangedEvent() is never invoked.  This is the
main problem that I am experiencing.

Any insights ?

Thanks

> Hi,
>
[quoted text clipped - 163 lines]
> >> }
> >> }
Gaurav Vaish (www.EduJini.IN) - 15 Aug 2006 04:50 GMT
Let me give it a shot by creating a dummy 'UserControl' on my own.

Signature

Happy Hacking,
Gaurav Vaish | http://www.mastergaurav.org
http://www.edujini.in | http://webservices.edujini.in
-------------------

> Hello Gaurav,
>
[quoted text clipped - 188 lines]
>> >> }
>> >> }
Gaurav Vaish (www.EduJini.IN) - 15 Aug 2006 05:39 GMT
Problem solved.
btw, the hidden field would be required because of the following reason:

For each ClientID that appears in the form and the control corresponding to
the same, the IPostBackDataHandler methods would be called.
And for no else.

Here's a trick:

Add a hidden field during 'Render' to the output.

You may download the code (that I wrote) from the following URL:
http://www.edujini.in/samples/ASP.Net/2.0/DataHandlerControl.zip

Signature

Happy Hacking,
Gaurav Vaish | http://www.mastergaurav.org
http://www.edujini.in | http://webservices.edujini.in
-------------------

> Let me give it a shot by creating a dummy 'UserControl' on my own.
>
[quoted text clipped - 194 lines]
>>> >> }
>>> >> }
buzlite001@hotmail.com - 15 Aug 2006 20:54 GMT
Hello Gaurav,

Thanks for you attempt but it was not answering the initial problem.

The initial problem was that the MyUserControl is embedded in a
Datagrid control. Please checkout the file WebForm1.aspx in my previous
email.

With the configuration as shown in WebForm1.aspx, the user control is
embedded in a datagrid control.  When this file is executed and text is
entered into the user control textbox,  LoadPostData() of the user
control is invoked.  But even though LoadPostData() returns 'true', the
corresponding RaisePostDataChangedEvent() is not called.  This is the
problem I am trying to find a solution to.

By the way, I am using Visual Studio.NET 2003 with .NET framework 1.1.
I think you are using Visual Studio.NET 2005 with .NET framework 2.0.
Nevertheless, I do not know if this would affect the result.  I would
be curious though.

Thanks

> Problem solved.
> btw, the hidden field would be required because of the following reason:
[quoted text clipped - 220 lines]
> >>> >> }
> >>> >> }
Gaurav Vaish (www.EduJini.IN) - 16 Aug 2006 02:55 GMT
No problem.
Embed the control in DataGrid.... should not be a problem.

Did you try using my control in DataGrid?

Signature

Happy Hacking,
Gaurav Vaish | http://www.mastergaurav.org
http://www.edujini.in | http://webservices.edujini.in
-------------------

> Hello Gaurav,
>
[quoted text clipped - 250 lines]
>> >>> >> }
>> >>> >> }
buzlite@sympatico.ca - 16 Aug 2006 19:20 GMT
Yes I have.  I had to adapt your code to Visual Studio.NET 2003 though.
It was exhibiting the same problem in that RaisePostDataChangedEvent()
of the user control is not being called even when LoadPostData() of the
user control returns 'true' back to the framework.

Hope you have better luck.

> No problem.
> Embed the control in DataGrid.... should not be a problem.
[quoted text clipped - 261 lines]
> >> >>> >> }
> >> >>> >> }
Alessandro Zifiglio - 17 Aug 2006 17:51 GMT
hi, the reason your postDataChanged event never makes it is because you have
the user control nested in a datagrid. The datagrid control internally
overrides the onBubbleEvent, and only raises command event, to which you can
get to using the ItemCommand method exposed by the datagrid, giving you a
central location to branch out. Only command events are raised and exposed
via the ItemCommand method because command events can contain CommandName
and CommandArgument properties which can futher be used to distinguish
between who fired what event(stored by you in CommandName property), and
also a chance to pass some custom data(via the commandArgument property) .

In your case you want to fire a non command event, so
1. Nothing will be fired in the DataGrids ItemCommand, and
2. the event is supressed since onbubble event is overridden by the datagrid
and no action is provided to handle any events raised other than command
events.

To work around, you can expose a textchanged event by your usercontrol
class, and attach the event declaratively as the following code snippet,
note OnTextChanged="WebUserControl11_TextChanged".

Another mistake i have seen in your code is that you rebind your datagrid in
page_load, whether its postback or not. If you do this, then the datagrid
will rebind, rebuilding everything and you lose state. This also will
execute before you user control gets a chance to inspect postdata changes.
So only rebind the grid, if its not a postback scenario.

Regards,
Alessandro Zifiglio
http://www.AsyncUI.net

<asp:DataGrid id="DataGrid1" runat="server" EnableViewState="True"
AutoGenerateColumns="False">
   <Columns>
    <asp:TemplateColumn HeaderText="Template Column1">
     <ItemTemplate>
      <uc1:WebUserControl1 id="WebUserControl11"
OnTextChanged="WebUserControl11_TextChanged"
runat="server"></uc1:WebUserControl1>
     </ItemTemplate>
    </asp:TemplateColumn>
   </Columns>
  </asp:DataGrid>

public void WebUserControl11_TextChanged(object sender, System.EventArgs e)
 {
  string text1 = (string)((WebUserControl1)sender).Text;
  Response.Write(text1);
 }

In your user control class you would be doing this to expose the public
event :
----------------------------------------------------------------------------------

public class WebUserControl1 : System.Web.UI.UserControl,
System.Web.UI.IPostBackDataHandler, System.Web.UI.INamingContainer
{
 protected System.Web.UI.WebControls.TextBox TextBox1;

 public event EventHandler TextChanged;
 public string Text
 {
  get
  {
   return this.TextBox1.Text;
  }

  set
  {
   this.TextBox1.Text = value;
  }
 }

 // return true only if the text has changed
 // otherwise false.
 public virtual bool LoadPostData(string postDataKey, NameValueCollection
postCollection)
 {

  String presentValue = Text;
  String postedValue = postCollection[postDataKey];
  if (postedValue == null)
   postedValue = string.Empty;
  if (!presentValue.Equals(postedValue))
  {
   return true;
  }
  return false;
 }

 public virtual void RaisePostDataChangedEvent()
 {
  OnTextChanged(EventArgs.Empty);
 }

 protected virtual void OnTextChanged(EventArgs e)
 {
  if (TextChanged != null)
   TextChanged(this,e);
 }

 override protected void OnInit(EventArgs e)
 {
  InitializeComponent();
  base.OnInit(e);

  if (Page != null)
  {
   Page.RegisterRequiresPostBack(this);
  }

 }

> Hello All,
>
[quoted text clipped - 146 lines]
> }
> }
buzlite@sympatico.ca - 18 Aug 2006 17:50 GMT
Thanks for the help Alessandro. Your explanation was very insightful.
Your code snippet worked like a charm.

Gaurav, if you're reading this posting, thanks to you too for helping.

Have a great day All.

> hi, the reason your postDataChanged event never makes it is because you have
> the user control nested in a datagrid. The datagrid control internally
[quoted text clipped - 258 lines]
> > }
> > }
Alessandro Zifiglio - 19 Aug 2006 10:52 GMT
your welcome.

Regards,
Alessandro Zifiglio
http://www.AsyncUI.net

> Thanks for the help Alessandro. Your explanation was very insightful.
> Your code snippet worked like a charm.
[quoted text clipped - 274 lines]
>> > }
>> > }
Gaurav Vaish (www.EduJini.IN) - 20 Aug 2006 12:09 GMT
> Gaurav, if you're reading this posting, thanks to you too for helping.

Always welcome... :-)

Signature

Happy Hacking,
Gaurav Vaish | http://www.mastergaurav.org
http://www.edujini.in | http://webservices.edujini.in
-------------------


Free Magazines

Get these publications absolutely FREE for up to 12 months. There are no hidden fees and no obligation. Simply choose a title, complete the application form and submit it. Read more ...

Oracle MagazineNetwork ComputingComputer WorldBio-IT WorldeWeekInformation WeekInfosecurity
 
Sign In
Join
My Latest Posts
My Monitored Threads
My Blog
My Photo Gallery
My Profile
My Homepage

Start New Thread
Enable EMail Alerts
Rate this Thread



©2009 Advenet LLC   Privacy Policy - Terms of Use
This website includes both content owned or controlled by Advenet as well as content owned or controlled by third parties.