473,320 Members | 1,946 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,320 software developers and data experts.

Custom build DataGridColumn event problem

OK.. phew. Playing with data grids for the past few days has been fun and a
huge learning experience..

My problem. I have a requirement to display a gird with a gird. Within the
embedded grid, theres a requirement to show a drop down menu list (this is a
control I downloaded online) in one of the columns. For the purposes of this
question, Ive implemented the drop down menu as a drop down list instead.
Ive got all this working at this point. Heres my problem:

1) When a person selects an item in the drop down list, I need the server to
autopost back and fire an event which I can handle on the sever side.
2) On the server side, I need to be able to figure out which drop down list
the event was fired for and what the selected value is.

Ive implemented the display of the column showing the drop down list in a
custom built DataGridColumn. All the code is below.

My Question:

1) How do I setup ONE postback event handler for ALL the drop downlist
controls being rendered dynamically in the embedded grid?
2) The event handler must be in the code-behind code that uses the custom
built DataGridColumn and should not be in the DataGridColumn code itself.
2) How do I figure out in that one event handler method, the drop down list
that threw the event, and the value of the selected item.

If you look towards the end of the method
CustomerDataGrid_OnItemDataBound(object sender, DataGridItemEventArgs e),
you'll find the code where I programmatically attach the new column. The
custom col code itself is the last snippet of code in this email.

Appreciate anyones help.

Girish

----------------
ASPX CODE
---------------

<%@ Page language="c#" Inherits="MasterDetail.CustomerOrderDataGrid"
EnableViewState="False" CodeBehind="CustomerOrderDataGrid.aspx.cs"
AutoEventWireup="false" %>
<HTML>
<LINK REL=StyleSheet HREF="menu.css" TYPE="text/css" />

<body style="FONT: x-small Verdana, Arial, sans-serif">
<!-- Begin Web Form -->
<form id="CustomerOrderDataGrid" method="post" runat="server">
<p><a href="/DayOfDotNet/">Parent Directory</a></p>
<!-- Begin DataGrid -->
<asp:DataGrid id="CustomerDataGrid" runat="server"
AutoGenerateColumns="False" CellPadding="2"
CellSpacing="0" Font-Names="Verdana, Arial, sans-serif"
BorderColor="Black" BorderWidth="1"
GridLines="Horizontal"
OnItemDataBound="CustomerDataGrid_OnItemDataBound" EnableViewState="False">
<AlternatingItemStyle BackColor="Tan"></AlternatingItemStyle>
<ItemStyle Font-Size="X-Small"></ItemStyle>
<HeaderStyle Font-Size="Small" Font-Names="Arial" Font-Bold="True"
ForeColor="White" BackColor="Maroon"></HeaderStyle>
<Columns>
<asp:BoundColumn Visible="False"
DataField="CustomerID"></asp:BoundColumn>
<asp:HyperLinkColumn
DataTextField="CustomerID"
DataNavigateUrlField="CustomerID"
DataNavigateUrlFormatString="OrderDetailDataGrid.a spx?customerid={0}"
HeaderText="ID"
ItemStyle-VerticalAlign="Top" />

<asp:TemplateColumn HeaderText="Customer">
<ItemStyle VerticalAlign="Top"></ItemStyle>
<ItemTemplate>
<b>
<%# DataBinder.Eval(Container.DataItem, "CompanyName") %>
</b>
<br>
<%# DataBinder.Eval(Container.DataItem, "Address" ) %>
<br>
<%# DataBinder.Eval(Container.DataItem, "City" ) %>
,
<%# DataBinder.Eval(Container.DataItem, "Region") %>
<%# DataBinder.Eval(Container.DataItem, "PostalCode" ) %>
<br>
<br>
<%# DataBinder.Eval(Container.DataItem, "ContactName" ) %>
<br>
<%# DataBinder.Eval(Container.DataItem, "ContactTitle" ) %>
<br>
<%# DataBinder.Eval(Container.DataItem, "Phone" ) %>
</ItemTemplate>
</asp:TemplateColumn>
<asp:TemplateColumn ItemStyle-VerticalAlign="Top"
HeaderText="Orders">
<%-- Embedded DataGrid will go here --%>
</asp:TemplateColumn>
</Columns>
</asp:DataGrid>
<!-- End DataGrid -->
</form>
<!-- End Web Form -->
</body>
</HTML>

-------------------
CODE BEHIND
------------------
using System;
using System.Data;
using System.Data.SqlClient;
using System.Drawing;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.HtmlControls;
using System.Configuration;

namespace MasterDetail
{
public class CustomerOrderDataGrid : System.Web.UI.Page
{
protected DataGrid CustomerDataGrid;
private DataSet ds = new DataSet();

private void Page_Load(object sender, System.EventArgs e)
{
string sqlStmt = "SELECT top 2 * FROM Customers; SELECT * FROM Orders";
string conString =
"server=localhost;database=Northwind;uid=sa;pwd=ti etronix;";

SqlDataAdapter sda = new SqlDataAdapter(sqlStmt, conString);

sda.Fill(ds);
ds.Tables[0].TableName = "Customers";
ds.Tables[1].TableName = "Orders";

CustomerDataGrid.DataSource = ds.Tables["Customers"];
CustomerDataGrid.DataBind();
}

//Use the OnItemDataBound event handler to dynamically add an embedded
DataGrid
protected void CustomerDataGrid_OnItemDataBound(object sender,
DataGridItemEventArgs e)
{
//When each row is created in the DataGrid, eval the ItemType
if(e.Item.ItemType == ListItemType.Item ||
e.Item.ItemType == ListItemType.AlternatingItem)
{
//If the ItemType is Item or AlternatingItem,
//Create a new DataGrid object named OrdersDataGrid
DataGrid OrdersDataGrid = new DataGrid();

//Format the DataGrid to look cool.
OrdersDataGrid.BorderWidth = (Unit)1;
OrdersDataGrid.CellPadding = 4;
OrdersDataGrid.CellSpacing = 0;
OrdersDataGrid.GridLines = GridLines.Horizontal;
OrdersDataGrid.BorderColor = Color.FromName("Black");

OrdersDataGrid.ItemStyle.Font.Name = "Verdana";
OrdersDataGrid.ItemStyle.Font.Size = FontUnit.XSmall;

OrdersDataGrid.AlternatingItemStyle.BackColor =
Color.FromName("LightGray");

OrdersDataGrid.ShowHeader = true;
OrdersDataGrid.HeaderStyle.BackColor = Color.FromName("Black");
OrdersDataGrid.HeaderStyle.ForeColor = Color.FromName("White");
OrdersDataGrid.HeaderStyle.Font.Bold = true;
OrdersDataGrid.HeaderStyle.Font.Size = FontUnit.XSmall;
//Do not autogenerate columns.
OrdersDataGrid.AutoGenerateColumns = false;

//Add a series of BoundColumns
//Order ID
BoundColumn bc = new BoundColumn();
//Set the BoundColumn Values
bc.HeaderText = "Order ID";
bc.DataField = "OrderID";
bc.ItemStyle.Wrap = false;
//Add the BoundColumn to the OrdersDataGrid.
OrdersDataGrid.Columns.Add(bc);

//Order Date
bc = new BoundColumn();
bc.HeaderText = "Order Date";
bc.DataField = "OrderDate";
bc.DataFormatString="{0:d}";
bc.ItemStyle.Wrap = false;
OrdersDataGrid.Columns.Add(bc);

//Required Date
bc = new BoundColumn();
bc.HeaderText = "Required Date";
bc.DataField = "RequiredDate";
bc.DataFormatString="{0:d}";
bc.ItemStyle.Wrap = false;
OrdersDataGrid.Columns.Add(bc);

//Shipped Date
bc = new BoundColumn();
bc.HeaderText = "Shipped Date";
bc.DataField = "ShippedDate";
bc.DataFormatString="{0:d}";
bc.ItemStyle.Wrap = false;
OrdersDataGrid.Columns.Add(bc);

// ADD THE CUSTOM BUILT COL HERE
DropDownListColumn DDLC = new DropDownListColumn();
DDLC.HeaderText = "My DDL";
OrdersDataGrid.Columns.Add(DDLC);

//End BoundColumns

//Get the Authors DataView and filter it for the current ISBN
DataView _orders = ds.Tables["Orders"].DefaultView;
_orders.RowFilter = "CustomerID='" + e.Item.Cells[0].Text + "'";

//Bind the DataGrid.
OrdersDataGrid.DataSource = _orders;
OrdersDataGrid.DataBind();

e.Item.Cells[3].Controls.Add(OrdersDataGrid);
}
}
override protected void OnInit(EventArgs e)
{
//
// CODEGEN: This call is required by the ASP.NET Web Form Designer.
//
InitializeComponent();
base.OnInit(e);
}

private void InitializeComponent()
{
this.Load += new System.EventHandler(this.Page_Load);
}
}
}

----------------------------------
Custom built data Grid col code
-----------------------------------
using System;
using System.Web.UI.WebControls;

namespace MasterDetail
{

public class DropDownListColumn : DataGridColumn
{
public DropDownListColumn() : base()
{
}

public override void InitializeCell(TableCell cell, int columnIndex,
ListItemType itemType)
{
base.InitializeCell(cell, columnIndex, itemType);

switch (itemType)
{
case ListItemType.EditItem:
case ListItemType.Item:
case ListItemType.AlternatingItem:
case ListItemType.SelectedItem:
cell.DataBinding += new EventHandler(this.ItemDataBinding);
DropDownList DLL = new DropDownList();
cell.Controls.Add( DLL );
break;
case ListItemType.Header:
break;
}

}

private void ItemDataBinding(object sender, EventArgs e)
{
TableCell cell = (TableCell)sender;
DropDownList DDL1 = (DropDownList)cell.Controls[0];
DDL1.Items.Add(new ListItem("one","1"));
DDL1.Items.Add(new ListItem("two","2"));
DDL1.Items.Add(new ListItem("three","3"));
}
}
}
Nov 19 '05 #1
7 3315
"Girish" wrote:
My Question:

1) How do I setup ONE postback event handler for ALL the drop downlist
controls being rendered dynamically in the embedded grid?
2) The event handler must be in the code-behind code that uses the custom
built DataGridColumn and should not be in the DataGridColumn code itself.
2) How do I figure out in that one event handler method, the drop down list
that threw the event, and the value of the selected item.


You can have the dropdownlist raise the SelectedIndexChanged event and then
trap the event (in the codebehind of the Page class, as you wanted) using
Event Bubbling. Lookup for samples on Event Bubbling on the MSDN library.

Consider though the size of the downloaded page. If every row of your
DataGrid were to repeat the same data for the dropdownlist then your page can
easily run over 1 megabyte in size (when handling real data). I would either:

1. Add an EditCommandButton in the DataGrid and leave the DropDownList in
the EditItemTemplate of one column. The DropDownList will only be displayed
in one row at a time when you bind it to its DataSource (this happens during
your handling the EditItem event). In this scenario the Update button would
raise the ItemCommand event. In processing the ItemCommand event you can get
both:

a. The ItemIndex of the grid where the postback occurred:
e.Item.ItemIndex, and
b. A reference to the dropdown list:
(DropDownList)e.Item.Cells[x].Controls[0]
(where x = the column no).

2. Replace the DropDownList by a TextBox and use client-side Javascript
to transform an xml data document using xslt to display a list of matching
results as demonstrated on this page:
http://www.societopia.net/samples/textbox.htm

--
http://www.webswapp.com
http://www.societopia.net

Nov 19 '05 #2
Appreciate the insight into page load size. I dont think this will be an
issue since we will be working with barely 10 rows per page.

I looked at Event Bubbling, but it requires that my DropDownListColumn
inherit from class Control. My DropDownListColumn already inherits from
DataGridColumn so i cant multiple inherit... im sure im missing something
simple here. pse advice.

thanks,
Girish
"Phillip Williams" <Ph**************@webswapp.com> wrote in message
news:56**********************************@microsof t.com...
"Girish" wrote:
My Question:

1) How do I setup ONE postback event handler for ALL the drop downlist
controls being rendered dynamically in the embedded grid?
2) The event handler must be in the code-behind code that uses the custom
built DataGridColumn and should not be in the DataGridColumn code itself.
2) How do I figure out in that one event handler method, the drop down
list
that threw the event, and the value of the selected item.


You can have the dropdownlist raise the SelectedIndexChanged event and
then
trap the event (in the codebehind of the Page class, as you wanted) using
Event Bubbling. Lookup for samples on Event Bubbling on the MSDN library.

Consider though the size of the downloaded page. If every row of your
DataGrid were to repeat the same data for the dropdownlist then your page
can
easily run over 1 megabyte in size (when handling real data). I would
either:

1. Add an EditCommandButton in the DataGrid and leave the DropDownList
in
the EditItemTemplate of one column. The DropDownList will only be
displayed
in one row at a time when you bind it to its DataSource (this happens
during
your handling the EditItem event). In this scenario the Update button
would
raise the ItemCommand event. In processing the ItemCommand event you can
get
both:

a. The ItemIndex of the grid where the postback occurred:
e.Item.ItemIndex, and
b. A reference to the dropdown list:
(DropDownList)e.Item.Cells[x].Controls[0]
(where x = the column no).

2. Replace the DropDownList by a TextBox and use client-side
Javascript
to transform an xml data document using xslt to display a list of matching
results as demonstrated on this page:
http://www.societopia.net/samples/textbox.htm

--
http://www.webswapp.com
http://www.societopia.net

Nov 19 '05 #3
This is a quick modification of your code to make the Event Bubbling works
http://www.societopia.net/samples/webform6.aspx

If I had more time I could have probably created a more elaborate custom
event.

I would still prefer the EditItem Template strategy as I mentioned in the
previous email. It is much cleaner.

Phillip
--
http://www.webswapp.com
"Girish" wrote:
Appreciate the insight into page load size. I dont think this will be an
issue since we will be working with barely 10 rows per page.

I looked at Event Bubbling, but it requires that my DropDownListColumn
inherit from class Control. My DropDownListColumn already inherits from
DataGridColumn so i cant multiple inherit... im sure im missing something
simple here. pse advice.

thanks,
Girish
"Phillip Williams" <Ph**************@webswapp.com> wrote in message
news:56**********************************@microsof t.com...
"Girish" wrote:
My Question:

1) How do I setup ONE postback event handler for ALL the drop downlist
controls being rendered dynamically in the embedded grid?
2) The event handler must be in the code-behind code that uses the custom
built DataGridColumn and should not be in the DataGridColumn code itself.
2) How do I figure out in that one event handler method, the drop down
list
that threw the event, and the value of the selected item.


You can have the dropdownlist raise the SelectedIndexChanged event and
then
trap the event (in the codebehind of the Page class, as you wanted) using
Event Bubbling. Lookup for samples on Event Bubbling on the MSDN library.

Consider though the size of the downloaded page. If every row of your
DataGrid were to repeat the same data for the dropdownlist then your page
can
easily run over 1 megabyte in size (when handling real data). I would
either:

1. Add an EditCommandButton in the DataGrid and leave the DropDownList
in
the EditItemTemplate of one column. The DropDownList will only be
displayed
in one row at a time when you bind it to its DataSource (this happens
during
your handling the EditItem event). In this scenario the Update button
would
raise the ItemCommand event. In processing the ItemCommand event you can
get
both:

a. The ItemIndex of the grid where the postback occurred:
e.Item.ItemIndex, and
b. A reference to the dropdown list:
(DropDownList)e.Item.Cells[x].Controls[0]
(where x = the column no).

2. Replace the DropDownList by a TextBox and use client-side
Javascript
to transform an xml data document using xslt to display a list of matching
results as demonstrated on this page:
http://www.societopia.net/samples/textbox.htm

--
http://www.webswapp.com
http://www.societopia.net


Nov 19 '05 #4
Thanks for your help again Phillip. I tend to be very inquisitive by
nature... my apologies in advance.. :)

1) What do you mean by "create a more elaborate custom event?" :)
2) To bubble events in user created controls, you have to inherit from
control and override RaiseBubbleEvent . Why is this? Why cant you get away
with what you did in your example?

If you could point me to articles, that would also be helpful rather than
typing out huge replies. :)

Thanks a mill again,
Girish
"Phillip Williams" <Ph**************@webswapp.com> wrote in message
news:CE**********************************@microsof t.com...
This is a quick modification of your code to make the Event Bubbling works
http://www.societopia.net/samples/webform6.aspx

If I had more time I could have probably created a more elaborate custom
event.

I would still prefer the EditItem Template strategy as I mentioned in the
previous email. It is much cleaner.

Phillip
--
http://www.webswapp.com
"Girish" wrote:
Appreciate the insight into page load size. I dont think this will be an
issue since we will be working with barely 10 rows per page.

I looked at Event Bubbling, but it requires that my DropDownListColumn
inherit from class Control. My DropDownListColumn already inherits from
DataGridColumn so i cant multiple inherit... im sure im missing something
simple here. pse advice.

thanks,
Girish
"Phillip Williams" <Ph**************@webswapp.com> wrote in message
news:56**********************************@microsof t.com...
> "Girish" wrote:
>
>> My Question:
>>
>> 1) How do I setup ONE postback event handler for ALL the drop downlist
>> controls being rendered dynamically in the embedded grid?
>> 2) The event handler must be in the code-behind code that uses the
>> custom
>> built DataGridColumn and should not be in the DataGridColumn code
>> itself.
>> 2) How do I figure out in that one event handler method, the drop down
>> list
>> that threw the event, and the value of the selected item.
>
> You can have the dropdownlist raise the SelectedIndexChanged event and
> then
> trap the event (in the codebehind of the Page class, as you wanted)
> using
> Event Bubbling. Lookup for samples on Event Bubbling on the MSDN
> library.
>
> Consider though the size of the downloaded page. If every row of your
> DataGrid were to repeat the same data for the dropdownlist then your
> page
> can
> easily run over 1 megabyte in size (when handling real data). I would
> either:
>
> 1. Add an EditCommandButton in the DataGrid and leave the
> DropDownList
> in
> the EditItemTemplate of one column. The DropDownList will only be
> displayed
> in one row at a time when you bind it to its DataSource (this happens
> during
> your handling the EditItem event). In this scenario the Update button
> would
> raise the ItemCommand event. In processing the ItemCommand event you
> can
> get
> both:
>
> a. The ItemIndex of the grid where the postback occurred:
> e.Item.ItemIndex, and
> b. A reference to the dropdown list:
> (DropDownList)e.Item.Cells[x].Controls[0]
> (where x = the column no).
>
> 2. Replace the DropDownList by a TextBox and use client-side
> Javascript
> to transform an xml data document using xslt to display a list of
> matching
> results as demonstrated on this page:
> http://www.societopia.net/samples/textbox.htm
>
> --
> http://www.webswapp.com
> http://www.societopia.net
>


Nov 19 '05 #5
"girish" wrote:
Thanks for your help again Phillip. I tend to be very inquisitive by
nature... my apologies in advance.. :)
You are welcome. I get to learn too.

1) What do you mean by "create a more elaborate custom event?" :)
In this example I had to pass the primary key of the record as the ID of the
dropdownlist control to discover the GridDataItem.ItemIndex. There might be a
better way of doing that.
2) To bubble events in user created controls, you have to inherit from
control and override RaiseBubbleEvent . Why is this? Why cant you get away
with what you did in your example?


http://msdn.microsoft.com/library/de...mmandevent.asp

In this sample you had your parent Grid on the webform already and added the
code for the child grid in the same page of the codeBehind. This is a just a
proof of concept. However if you intend to deploy them in production you
might create each as separate control inherited from the datagrid and have to
bubble events from the child grid to the parent and then from the parent to
the page that contain it or any other container that you have customized.

Phillip
---
www.societopia.net
www.webswapp.com

Nov 19 '05 #6

"girish" wrote:
Thanks for your help again Phillip. I tend to be very inquisitive by
nature... my apologies in advance.. :)

1) What do you mean by "create a more elaborate custom event?" :)


I found a couple of nice and clear samples on the MSDN library to help you
create event delegates and custom event data classes that you might be
interested in:

http://msdn.microsoft.com/library/de...ini-sample.asp

http://msdn.microsoft.com/library/de...trolsample.asp

Hope this helps.

Phillip
---
http://www.webswapp.com
http://www.societopia.net

Nov 19 '05 #7
Thanks Phillip. :) Youve been a great help.

g

"Phillip Williams" <Ph**************@webswapp.com> wrote in message
news:9C**********************************@microsof t.com...

"girish" wrote:
Thanks for your help again Phillip. I tend to be very inquisitive by
nature... my apologies in advance.. :)

1) What do you mean by "create a more elaborate custom event?" :)


I found a couple of nice and clear samples on the MSDN library to help you
create event delegates and custom event data classes that you might be
interested in:

http://msdn.microsoft.com/library/de...ini-sample.asp

http://msdn.microsoft.com/library/de...trolsample.asp

Hope this helps.

Phillip
---
http://www.webswapp.com
http://www.societopia.net

Nov 19 '05 #8

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

3
by: dave | last post by:
I have created a control that inherits from datagrid. Before I render the grid html I want to create a linkbutton. I am using the following code to do so Dim lnk As New LinkButto lnk.Text =...
2
by: Andrew | last post by:
I am trying to set the column information - which ones I want displayed and how with the web grid control. The interface has some big differences when compared to the winform. Is this possible...
2
by: Jay Walker | last post by:
I created a custom DataGridColumn based on Marcie Robillard's MSDN Article: Creating Custom Columns for the ASP.NET Datagrid...
2
by: Suzanne | last post by:
Hi all, I'm reposting this message as I'm experiencing this problem more and more frequently : I really hope someone out there can help me as I've been tearing my hair out on this one for a...
2
by: Peter Ritchie | last post by:
In VS/VC 2003: Simple question: for the Custom Build Step for the project (right click the project in the Solution Explorer, select "Properties", select the "Custom Build Step" in the...
1
by: David Herbst | last post by:
Enterprise Library Jan 2006 with Visual Studio 2005 on Windows 2000 Server sp4. My custom exception formatter fails with a "Unable to handle exception: 'LoggingExceptionHandler'." exception. ...
3
by: bill | last post by:
I am using VS2005 to build a web form dynamically. I'm using AddHandler to connect a custom event handler to the TextChanged event of dynamically added textbox controls. Data entered in the...
15
by: rizwanahmed24 | last post by:
Hello i have made a custom control. i have placed a panel on it. I want this panel to behave just like the normal panel. The problem i was having is that the panel on my custom control doesnt...
0
hyperpau
by: hyperpau | last post by:
Before anything else, I am not a very technical expert when it comes to VBA coding. I learned most of what I know by the excellent Access/VBA forum from bytes.com (formerly thescripts.com). Ergo, I...
0
by: DolphinDB | last post by:
The formulas of 101 quantitative trading alphas used by WorldQuant were presented in the paper 101 Formulaic Alphas. However, some formulas are complex, leading to challenges in calculation. Take...
0
by: DolphinDB | last post by:
Tired of spending countless mintues downsampling your data? Look no further! In this article, you’ll learn how to efficiently downsample 6.48 billion high-frequency records to 61 million...
0
by: ryjfgjl | last post by:
ExcelToDatabase: batch import excel into database automatically...
0
isladogs
by: isladogs | last post by:
The next Access Europe meeting will be on Wednesday 6 Mar 2024 starting at 18:00 UK time (6PM UTC) and finishing at about 19:15 (7.15PM). In this month's session, we are pleased to welcome back...
0
by: Vimpel783 | last post by:
Hello! Guys, I found this code on the Internet, but I need to modify it a little. It works well, the problem is this: Data is sent from only one cell, in this case B5, but it is necessary that data...
0
by: jfyes | last post by:
As a hardware engineer, after seeing that CEIWEI recently released a new tool for Modbus RTU Over TCP/UDP filtering and monitoring, I actively went to its official website to take a look. It turned...
1
by: PapaRatzi | last post by:
Hello, I am teaching myself MS Access forms design and Visual Basic. I've created a table to capture a list of Top 30 singles and forms to capture new entries. The final step is a form (unbound)...
0
by: Defcon1945 | last post by:
I'm trying to learn Python using Pycharm but import shutil doesn't work
0
by: Shællîpôpï 09 | last post by:
If u are using a keypad phone, how do u turn on JavaScript, to access features like WhatsApp, Facebook, Instagram....

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.