Bug in _EditCommand, event didn't fire? +my solution

R

Roberto C

Hello,

I had a problem that the _EditCommand didn't fire when the event was created in the .vb code. I did like this:

1. I created a datagrid (dgrdProducts) in design view.

2. Then I created the columns in code, like this, the method is called from Page_Load:

Private Sub CreateColumns()
Dim ProductID As New BoundColumn
Dim ProductName As New BoundColumn
Dim UnitPrice As New BoundColumn
Dim EditCol As New EditCommandColumn

With ProductID
.HeaderText = "Product ID"
.DataField = "ProductID"
.ReadOnly = True
End With

With ProductName
.HeaderText = "Product Name"
.DataField = "ProductName"
End With

With UnitPrice
.HeaderText = "Price"
.DataField = "UnitPrice"
.DataFormatString = "{0:c}"
End With

With EditCol
.EditText = "Edit!"
.UpdateText = "Update!"
.CancelText = "Cancel!"
End With

With dgrdProducts.Columns
.Add(ProductID)
.Add(ProductName)
.Add(UnitPrice)
.Add(EditCol)
End With
End Sub


3. I then created the Edit event like this:

Private Sub dgrdProducts_EditCommand(ByVal source As Object, ByVal e As System.Web.UI.WebControls.DataGridCommandEventArgs) Handles dgrdProducts.EditCommand

dgrdProducts.EditItemIndex = e.Item.ItemIndex
BindDataGrid()

End Sub


4. Here is the code for Page_Load and the method BindDataGrid:

Private Sub Page_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
conNorthwind = New SqlConnection("Server=localhost;UID=sa;PWD=;Database=Northwind")

With dgrdProducts
.DataKeyField = "ProductID"
.AutoGenerateColumns = False
.CellPadding = 10
.HeaderStyle.BackColor = Color.Salmon
End With

CreateColumns()

If Not IsPostBack Then
BindDataGrid()
End If
End Sub

Private Sub BindDataGrid()
cmdSql = New SqlCommand("Select * From Products", conNorthwind)
conNorthwind.Open()
dgrdProducts.DataSource = cmdSql.ExecuteReader()
dgrdProducts.DataBind()
conNorthwind.Close()
End Sub

When I tried to fire the event, NOTHING happened. It seemed like the page forgot that the edit event existed, strange?


The solution is that I had to create the datagrid in HTML on the .aspx page like this:

<asp:DataGrid
ID="dgrdProducts"
OnEditCommand="dgrdProducts_EditCommand"
DataKeyField="ProductID"
AutoGenerateColumns="False"
CellPadding="10"
HeaderStyle-BackColor="Salmon"
Runat="Server">
<Columns>
<asp:BoundColumn
HeaderText="Product ID"
DataField="ProductID"
ReadOnly="True" />
<asp:BoundColumn
HeaderText="Product Name"
DataField="ProductName" />
<asp:BoundColumn
HeaderText="Price"
DataField="UnitPrice"
DataFormatString="{0:c}" />
<asp:EditCommandColumn
EditText="Edit!" />
</Columns>
</asp:DataGrid>

and then I did a small change in the event code, like this (From "Private" to "Protected" and removed "Handles dgrdProducts.EditCommand"), and then everything worked perfect, the event did fire:

Protected Sub dgrdProducts_EditCommand(ByVal s As Object, ByVal e As DataGridCommandEventArgs)
dgrdProducts.EditItemIndex = e.Item.ItemIndex
BindDataGrid()
End Sub


Can someone tell me why it didn't work when I tried to create the event in the .vb code, is that a bug in Framework 1.1? I try not to mess around to much with the HTML, I want to as much as possible in the .vb code.

Thanks in advance!

/Roberto Cusicanqui
 
R

Rick Spiewak

The fact that you're creating the columns on each page load suggests that you would also want to use AddHandler to attach the event to the datagrid - just leave off the "Handles" and add the AddHandler.

But, why do that? If you already know what columns you want, why not create them in design view? I believe that this would avoid the problem.
Hello,

I had a problem that the _EditCommand didn't fire when the event was created in the .vb code. I did like this:

1. I created a datagrid (dgrdProducts) in design view.

2. Then I created the columns in code, like this, the method is called from Page_Load:

Private Sub CreateColumns()
Dim ProductID As New BoundColumn
Dim ProductName As New BoundColumn
Dim UnitPrice As New BoundColumn
Dim EditCol As New EditCommandColumn

With ProductID
.HeaderText = "Product ID"
.DataField = "ProductID"
.ReadOnly = True
End With

With ProductName
.HeaderText = "Product Name"
.DataField = "ProductName"
End With

With UnitPrice
.HeaderText = "Price"
.DataField = "UnitPrice"
.DataFormatString = "{0:c}"
End With

With EditCol
.EditText = "Edit!"
.UpdateText = "Update!"
.CancelText = "Cancel!"
End With

With dgrdProducts.Columns
.Add(ProductID)
.Add(ProductName)
.Add(UnitPrice)
.Add(EditCol)
End With
End Sub


3. I then created the Edit event like this:

Private Sub dgrdProducts_EditCommand(ByVal source As Object, ByVal e As System.Web.UI.WebControls.DataGridCommandEventArgs) Handles dgrdProducts.EditCommand

dgrdProducts.EditItemIndex = e.Item.ItemIndex
BindDataGrid()

End Sub


4. Here is the code for Page_Load and the method BindDataGrid:

Private Sub Page_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
conNorthwind = New SqlConnection("Server=localhost;UID=sa;PWD=;Database=Northwind")

With dgrdProducts
.DataKeyField = "ProductID"
.AutoGenerateColumns = False
.CellPadding = 10
.HeaderStyle.BackColor = Color.Salmon
End With

CreateColumns()

If Not IsPostBack Then
BindDataGrid()
End If
End Sub

Private Sub BindDataGrid()
cmdSql = New SqlCommand("Select * From Products", conNorthwind)
conNorthwind.Open()
dgrdProducts.DataSource = cmdSql.ExecuteReader()
dgrdProducts.DataBind()
conNorthwind.Close()
End Sub

When I tried to fire the event, NOTHING happened. It seemed like the page forgot that the edit event existed, strange?


The solution is that I had to create the datagrid in HTML on the .aspx page like this:

<asp:DataGrid
ID="dgrdProducts"
OnEditCommand="dgrdProducts_EditCommand"
DataKeyField="ProductID"
AutoGenerateColumns="False"
CellPadding="10"
HeaderStyle-BackColor="Salmon"
Runat="Server">
<Columns>
<asp:BoundColumn
HeaderText="Product ID"
DataField="ProductID"
ReadOnly="True" />
<asp:BoundColumn
HeaderText="Product Name"
DataField="ProductName" />
<asp:BoundColumn
HeaderText="Price"
DataField="UnitPrice"
DataFormatString="{0:c}" />
<asp:EditCommandColumn
EditText="Edit!" />
</Columns>
</asp:DataGrid>

and then I did a small change in the event code, like this (From "Private" to "Protected" and removed "Handles dgrdProducts.EditCommand"), and then everything worked perfect, the event did fire:

Protected Sub dgrdProducts_EditCommand(ByVal s As Object, ByVal e As DataGridCommandEventArgs)
dgrdProducts.EditItemIndex = e.Item.ItemIndex
BindDataGrid()
End Sub


Can someone tell me why it didn't work when I tried to create the event in the .vb code, is that a bug in Framework 1.1? I try not to mess around to much with the HTML, I want to as much as possible in the .vb code.

Thanks in advance!

/Roberto Cusicanqui
 
J

Jeffrey Tan[MSFT]

Hi Roberto,

Based on my understanding, you want to dynamically add columns to webform
datagrid, also you want to handle datagrid.ItemCommand event.
============================

Actually, your problem of the DataGrid ItemCommand event does not fire is
due to the dynamically added columns did not load its viewstate correct.

Normally, DataGrid's columns will persist in viewstate between postback.
That is, after the initial load, the entire columns data will be persisted
in viewstate, then when postback, in LoadViewState method, asp.net will
read these viewstate and associate the viewstate data with the columns in
datagrid.

In your scenario, after first initial load, your dynamically added columns
are added in viewstate(Because they are added before SaveViewState method),
but when postback by the "Edit!" linkbutton. Note LoadViewState is executed
before Page.Load event, so in LoadViewState, the asp.net find that there
are no related columns in your datagrid to associate with the viewstate,
asp.net will discard the viewstate. Then, your columns are dynamically
added Load event, everything will gone away.

So you should add the columns before LoadViewState method, such as in
Page.Init event, or in LoadViewState period. Then in LoadViewState period,
asp.net can associate the viewstate with columns correctly. Do like this:

Private Sub dgrdProducts_Init(ByVal sender As Object, ByVal e As
System.EventArgs) Handles dgrdProducts.Init
CreateColumns()
End Sub

For more information, please refer to below article "Adding Columns
Dynamically" section:
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dv_vstechar
t/html/vbtchTopQuestionsAboutASPNETDataGridServerControl.asp

===========================
Please apply my suggestion above and let me know if it helps resolve your
problem.


Thank you for your patience and cooperation. If you have any questions or
concerns, please feel free to post it in the group. I am standing by to be
of assistance.

Best regards,
Jeffrey Tan
Microsoft Online Partner Support
Get Secure! - www.microsoft.com/security
This posting is provided "as is" with no warranties and confers no rights.
 
J

Jeffrey Tan[MSFT]

Hi Roberto,

Does my reply make sense to you? Do you still have any concern on this
issue?

Please feel free to feedback. Thanks

Best regards,
Jeffrey Tan
Microsoft Online Partner Support
Get Secure! - www.microsoft.com/security
This posting is provided "as is" with no warranties and confers no rights.
 

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

No members online now.

Forum statistics

Threads
473,781
Messages
2,569,615
Members
45,295
Latest member
EmilG1510

Latest Threads

Top