Dynamically added LinkButton event handling

G

Guest

Hi,

I have a strange issue occurring with LinkButtons that are dynamically added
to each (data) row of my DataGrid on that grid's ItemDataBound event. Each
LinkButton is assigned its own event handler to deal with the Command event,
but for some reason I can get this to work in a C# project but not in a newly
created VB.NET one.

The relevant VB.NET is as follows:

''' <summary>
''' Bind the columns within the grid to runtime data
''' </summary>
''' <param name="sender"></param>
''' <param name="e"></param>
Protected Sub MattersGrid_ItemDataBound(ByVal sender As Object,
ByVal e As DataGridItemEventArgs)
If (e.Item.ItemType = ListItemType.Item OrElse e.Item.ItemType =
ListItemType.AlternatingItem OrElse e.Item.ItemType =
ListItemType.SelectedItem) Then
Dim l_link As New LinkButton
With l_link
.ID = "MatterSelectedButton"
.Text = DataBinder.Eval(e.Item.DataItem,
"Name").ToString()

If e.Item.ItemType = ListItemType.SelectedItem Then
.BackColor = System.Drawing.Color.LightYellow
Else
.CommandName = "ItemSelected"
.CommandArgument = e.Item.ItemIndex
AddHandler .Command, AddressOf MattersGrid_Command
End If
End With

' the 1th column is the templatecolumn in the grid
e.Item.Cells(2).Controls.Add(l_link)
End If
End Sub

''' <summary>
''' Handle click-commands performed on the grid (TODO; currently
misbehaving)
''' </summary>
''' <param name="sender"></param>
''' <param name="e"></param>
Protected Sub MattersGrid_Command(ByVal sender As Object, ByVal e As
CommandEventArgs)
If (e.CommandName = "ItemSelected") Then
MattersGrid.SelectedIndex =
Integer.Parse(e.CommandArgument.ToString)
RebindDG()
End If
End Sub

and the similar, but working code in C# is:

/// <summary>
/// Bind the columns within the grid to runtime data
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
protected void TestDataGrid_ItemDataBound(object sender,
DataGridItemEventArgs e)
{
if (pr_debug) this.Page.Trace.Warn("TestDataGrid_ItemDataBound");

// only display the link on standard grid items (not
edit/select/header etc.)
if (e.Item.ItemType == ListItemType.Item || e.Item.ItemType ==
ListItemType.AlternatingItem)
{
LinkButton l_link = new LinkButton();
l_link.Text = DataBinder.Eval(e.Item.DataItem,
"ID").ToString();
l_link.CommandName = "ItemSelected";
l_link.CommandArgument = e.Item.ItemIndex.ToString();
l_link.Command += new
CommandEventHandler(TestDataGrid_Command);

// the 1th column is the templatecolumn in the grid
e.Item.Cells[1].Controls.Add(l_link);
}
}

/// <summary>
/// Handle click-commands performed on the grid
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
protected void TestDataGrid_Command(Object sender, CommandEventArgs e)
{
if (pr_debug) this.Page.Trace.Warn("TestDataGrid_Command");

if (e.CommandName == "ItemSelected")
{
TestDataGrid.SelectedIndex =
int.Parse(e.CommandArgument.ToString());

RebindDG();
}
}

I know there are a couple of subtle differences between the two, but the
core is essentially the same. However, the VB.NET one never fires the Command
event but the C# one does.

The DataGrid in both cases is also dynamically added to the parent control
(a Web Part) and is a 'global' protected object.

Any ideas?

Thanks,

Marc
 
G

Guest

Marc,

It looks like your VB is not working due to extra filter on If condition:
e.Item.ItemType = ListItemType.SelectedItem
as in this case you do not add the handler to the link. As your
ItemDataBound event occurs after postback, your condition within the code
skips event hookup.

Anyhow with the grid you do not have to hook command events to every link
individually - the grid will do it for you in bulk if you just add RowCommand
event handler to the grid during Page_Init event (you only need to do it
during Postback)

Marc Woolfson said:
Hi,

I have a strange issue occurring with LinkButtons that are dynamically added
to each (data) row of my DataGrid on that grid's ItemDataBound event. Each
LinkButton is assigned its own event handler to deal with the Command event,
but for some reason I can get this to work in a C# project but not in a newly
created VB.NET one.

The relevant VB.NET is as follows:

''' <summary>
''' Bind the columns within the grid to runtime data
''' </summary>
''' <param name="sender"></param>
''' <param name="e"></param>
Protected Sub MattersGrid_ItemDataBound(ByVal sender As Object,
ByVal e As DataGridItemEventArgs)
If (e.Item.ItemType = ListItemType.Item OrElse e.Item.ItemType =
ListItemType.AlternatingItem OrElse e.Item.ItemType =
ListItemType.SelectedItem) Then
Dim l_link As New LinkButton
With l_link
.ID = "MatterSelectedButton"
.Text = DataBinder.Eval(e.Item.DataItem,
"Name").ToString()

If e.Item.ItemType = ListItemType.SelectedItem Then
.BackColor = System.Drawing.Color.LightYellow
Else
.CommandName = "ItemSelected"
.CommandArgument = e.Item.ItemIndex
AddHandler .Command, AddressOf MattersGrid_Command
End If
End With

' the 1th column is the templatecolumn in the grid
e.Item.Cells(2).Controls.Add(l_link)
End If
End Sub

''' <summary>
''' Handle click-commands performed on the grid (TODO; currently
misbehaving)
''' </summary>
''' <param name="sender"></param>
''' <param name="e"></param>
Protected Sub MattersGrid_Command(ByVal sender As Object, ByVal e As
CommandEventArgs)
If (e.CommandName = "ItemSelected") Then
MattersGrid.SelectedIndex =
Integer.Parse(e.CommandArgument.ToString)
RebindDG()
End If
End Sub

and the similar, but working code in C# is:

/// <summary>
/// Bind the columns within the grid to runtime data
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
protected void TestDataGrid_ItemDataBound(object sender,
DataGridItemEventArgs e)
{
if (pr_debug) this.Page.Trace.Warn("TestDataGrid_ItemDataBound");

// only display the link on standard grid items (not
edit/select/header etc.)
if (e.Item.ItemType == ListItemType.Item || e.Item.ItemType ==
ListItemType.AlternatingItem)
{
LinkButton l_link = new LinkButton();
l_link.Text = DataBinder.Eval(e.Item.DataItem,
"ID").ToString();
l_link.CommandName = "ItemSelected";
l_link.CommandArgument = e.Item.ItemIndex.ToString();
l_link.Command += new
CommandEventHandler(TestDataGrid_Command);

// the 1th column is the templatecolumn in the grid
e.Item.Cells[1].Controls.Add(l_link);
}
}

/// <summary>
/// Handle click-commands performed on the grid
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
protected void TestDataGrid_Command(Object sender, CommandEventArgs e)
{
if (pr_debug) this.Page.Trace.Warn("TestDataGrid_Command");

if (e.CommandName == "ItemSelected")
{
TestDataGrid.SelectedIndex =
int.Parse(e.CommandArgument.ToString());

RebindDG();
}
}

I know there are a couple of subtle differences between the two, but the
core is essentially the same. However, the VB.NET one never fires the Command
event but the C# one does.

The DataGrid in both cases is also dynamically added to the parent control
(a Web Part) and is a 'global' protected object.

Any ideas?

Thanks,

Marc
 
G

Guest

Hi Sergey,

Thanks for your reply. This extra condition just means that the LinkButton
will be added to the selected row in the VB.NET version but not the C#
version - this is required but I'm not event getting this far!

Your second point seems to be the problem I am experiencing - how do you
think I should modify the code to enable the desired event hookup? Do you
know why this may work in C# and not VB.NET?

I couldn't see a RowCommand for the grid, but there was the standard
ItemCommand one. I tried to implement this on the OnInit(), but it too didn't
fire when one of LinkButtons was clicked.

Thanks,

Marc
 
G

Guest

I have just converted the entire project to C#... and the problem still
exists. Any ideas?
 
M

Mark Rae

I have just converted the entire project to C#... and the problem still
exists. Any ideas?

Dynamically created controls need to be created in Page_PreInit or
Page_Init, otherwise their events don't get wired up properly...

You're creating them far too late in the page cycle...
 
G

Guest

I have managed to get this working by adding a ButtonColumn in place of the
TemplateColumn and using the grid's ItemCommand event to capture the required
event.

Thanks for your assistance!
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,968
Messages
2,570,153
Members
46,701
Latest member
XavierQ83

Latest Threads

Top