paulhudson Posted January 19, 2005 Posted January 19, 2005 (edited) I have a datagrid bound to a dataset. When selecting the onupdatecommand to accept changes I get the error message: "Object reference not set to an instance of an object" The datagrid: <asp:DataGrid id="dgr1" runat="server" DataKeyField="PlayerID" OnEditCommand="DoItemEdit" OnUpdateCommand="DoItemUpdate" OnCancelCommand="DoItemCancel"> Sub DoItemUpdate(ByVal sender As Object, ByVal e As DataGridCommandEventArgs) tpDataSet.AcceptChanges() dgr1.DataSource = dsTeamPlayer.Tables("LastTeamPlayers") dgr1.DataBind() End Sub Any ideas? Any help would make my day! Edited January 10, 2006 by PlausiblyDamp Quote
Administrators PlausiblyDamp Posted January 19, 2005 Administrators Posted January 19, 2005 Which line does the error occur on? If you step through the code in the debugger what are the values of the objects on the line that the error happens? Are you sure you are assigning valid instances to the variables? Quote Posting Guidelines FAQ Post Formatting Intellectuals solve problems; geniuses prevent them. -- Albert Einstein
paulhudson Posted January 19, 2005 Author Posted January 19, 2005 error line The error occurs at the line: tpDataSet.AcceptChanges() Unsure how to answer your other questions. I'm fairly recent to ASP.NET and I haven't been using visual studio. If you can advise how to get more information it would be much appreciated! All I can give is the stack trace: [NullReferenceException: Object reference not set to an instance of an object.] ASP.TeamList_aspx.DoItemUpdate(Object sender, DataGridCommandEventArgs e) in c:\admin\teamlist.aspx:186 System.Web.UI.WebControls.DataGrid.OnUpdateCommand(DataGridCommandEventArgs e) +111 System.Web.UI.WebControls.DataGrid.OnBubbleEvent(Object source, EventArgs e) +553 System.Web.UI.Control.RaiseBubbleEvent(Object source, EventArgs args) +31 System.Web.UI.WebControls.DataGridItem.OnBubbleEvent(Object source, EventArgs e) +120 System.Web.UI.Control.RaiseBubbleEvent(Object source, EventArgs args) +31 System.Web.UI.WebControls.LinkButton.OnCommand(CommandEventArgs e) +122 System.Web.UI.WebControls.LinkButton.RaisePostBackEvent(String eventArgument) +288 System.Web.UI.WebControls.LinkButton.System.Web.UI.IPostBackEventHandler.RaisePostBackEvent(String eventArgument) +5 System.Web.UI.Page.RaisePostBackEvent(IPostBackEventHandler sourceControl, String eventArgument) +11 System.Web.UI.Page.RaisePostBackEvent(NameValueCollection postData) +166 System.Web.UI.Page.ProcessRequestMain(Boolean includeStagesBeforeAsyncPoint, Boolean includeStagesAfterAsyncPoint) +5157 Quote
kahlua001 Posted January 19, 2005 Posted January 19, 2005 Don know if this code is the same as from your previous code, but where do you declare tpDataSet? By the time the code goes into this sub, has tpDataSet been declared with the new construct? like, tpDataSet = new dataset ? Quote
paulhudson Posted January 20, 2005 Author Posted January 20, 2005 (edited) kahlua001 The code is based on my previous posts - but I have been butchering it in order to get it working (unsuccessfully). Below is the full code - it is all there! I have a couple of fundamental flaws that I can identify. On first load all goes well, I fill a dataset from db then create a new dataset copying the data from original dataset and add another column. I have done this as a method of testing, don't see the need to keep it. The datagrid is bound to this data and all looks good. Now in the OnEditCommand, if I call the original sub BindData it goes into the edit mode as I expect (problem is the dataset is reloaded from database - so even if accept changes were successful they would be wiped!) If I try to bind the dataset to datagrid outside of the sub that creates dataset, I get the error message as originally posted. I do not understand how I use the dataset after page has been reloaded. I feel like I am missing a fundamental piece of the jigsaw. Hope my confusion makes sense.... Public sKey as string Public MatchDataID as string Public dsTeamPlayer As Dataset Public dsCopy As DataSet Public tpDataSet as Dataset Public Sub Page_Load() If Not Page.IsPostback Then BindData End If End Sub Public sub BindData() MatchDataID = Session("MatchDataID") sKey = Session("TeamID") Dim oConnect As New OleDbConnection(ConfigurationSettings.AppSettings("connString")) Dim oDR As OleDbDataAdapter = New OleDbDataAdapter oDR.SelectCommand = New OleDbCommand("spTeamLineUp" , oConnect) oDR.SelectCommand.CommandType = CommandType.StoredProcedure Dim oParam As OleDbParameter = oDR.SelectCommand.Parameters.Add("@ParamID", OleDbType.Integer) oParam.Value = sKey oParam.Direction = ParameterDirection.Input dsTeamPlayer = New Dataset() oDR.MissingSchemaAction = MissingSchemaAction.AddWithKey oDR.Fill(dsTeamPlayer, "LastTeamPlayers") NewDataSet End Sub Public Sub NewDataSet Dim dtTeamPlayers As DataTable = new DataTable("TeamPlayers") Dim tpDataColumn As DataColumn Dim tpDataRow As DataRow tpDataColumn = New DataColumn() tpDataColumn.DataType = System.Type.GetType("System.Int32") tpDataColumn.ColumnName = "PNumber" tpDataColumn.ReadOnly = False tpDataColumn.Unique = True tpDataColumn.AutoIncrement = False dtTeamPlayers.Columns.Add(tpDataColumn) tpDataColumn = New DataColumn() tpDataColumn.DataType = System.Type.GetType("System.Int32") tpDataColumn.ColumnName = "PlayerID" tpDataColumn.ReadOnly = False tpDataColumn.Unique = True tpDataColumn.AutoIncrement = False dtTeamPlayers.Columns.Add(tpDataColumn) tpDataColumn = New DataColumn() tpDataColumn.DataType = System.Type.GetType("System.String") tpDataColumn.ColumnName = "PlayerName" tpDataColumn.ReadOnly = False tpDataColumn.Unique = True tpDataColumn.AutoIncrement = False dtTeamPlayers.Columns.Add(tpDataColumn) tpDataColumn = New DataColumn() tpDataColumn.DataType = System.Type.GetType("System.String") tpDataColumn.ColumnName = "TPosition" tpDataColumn.ReadOnly = False tpDataColumn.Unique = True tpDataColumn.AutoIncrement = False dtTeamPlayers.Columns.Add(tpDataColumn) tpDataColumn = New DataColumn() tpDataColumn.DataType = System.Type.GetType("System.Int32") tpDataColumn.ColumnName = "TPositionID" tpDataColumn.ReadOnly = False tpDataColumn.Unique = True tpDataColumn.AutoIncrement = False dtTeamPlayers.Columns.Add(tpDataColumn) tpDataColumn = New DataColumn() tpDataColumn.DataType = System.Type.GetType("System.Int32") tpDataColumn.ColumnName = "Goals" tpDataColumn.ReadOnly = False tpDataColumn.Unique = False tpDataColumn.AutoIncrement = False dtTeamPlayers.Columns.Add(tpDataColumn) dim tpDataSet As DataSet = New DataSet() tpDataSet.Tables.Add(dtTeamPlayers) Dim PrimaryKeyColumns(0) As DataColumn PrimaryKeyColumns(0)= dtTeamPlayers.Columns("PlayerID") dtTeamPlayers.PrimaryKey = PrimaryKeyColumns Dim DataRowCopy as DataRow for each DataRowCopy in dsTeamPlayer.Tables(0).Rows tpDataRow = dtTeamPlayers.NewRow() tpDataRow("PNumber") = DataRowCopy("PNumber") tpDataRow("PlayerID") = DataRowCopy("PlayerID") tpDataRow("PlayerName") = DataRowCopy("PlayerName") tpDataRow("TPosition") = DataRowCopy("TPosition") tpDataRow("TPositionID") = DataRowCopy("TPositionID") tpDataRow("Goals") = "0" dtTeamPlayers.Rows.Add(tpDataRow) next dgr1.DataSource = tpDataSet.Tables("TeamPlayers") dgr1.DataBind() End sub Function GetTeamPositions() Dim oConnect As New OleDbConnection(ConfigurationSettings.AppSettings("connString")) Dim oCommand As New OleDbCommand("spTeamPositions", oConnect) oCommand.commandType = CommandType.StoredProcedure Try oConnect.Open() Return oCommand.ExecuteReader(CommandBehavior.CloseConnection) Catch oErr As Exception If oConnect.State <> ConnectionState.Closed Then oConnect.Close() End If lblErr.Text = oErr.Message & "<p/>" End Try End function Function GetTeamPlayers() Dim oConnect As New OleDbConnection(ConfigurationSettings.AppSettings("connString")) Dim oCommand As New OleDbCommand("spTeamPlayerList", oConnect) oCommand.commandType = CommandType.StoredProcedure dim oParam as OleDbParameter oParam = oCommand.Parameters.Add("@ParamID", _ OleDbType.Integer) oParam.Direction = ParameterDirection.Input oParam.Value = sKey Try oConnect.Open() Return oCommand.ExecuteReader(CommandBehavior.CloseConnection) Catch oErr As Exception If oConnect.State <> ConnectionState.Closed Then oConnect.Close() End If lblErr.Text = oErr.Message & "<p/>" End Try End function Sub DoItemEdit(ByVal Sender As Object, ByVal E As DataGridCommandEventArgs) dgr1.EditItemIndex = CInt(E.Item.ItemIndex) BindData ' [color=Red]this displays the dropdownlists/text boxes of edit mode! But it is refreshing the dataset to original state each time![/color] End Sub Sub DoItemUpdate(ByVal sender As Object, ByVal e As DataGridCommandEventArgs) tpDataSet.AcceptChanges() '[color=Red]this is where to obj ref error comes in![/color] dgr1.DataSource = tpDataSet.Tables("TeamPlayers") dgr1.DataBind() End Sub Sub DoItemCancel(ByVal Sender As Object, ByVal E As DataGridCommandEventArgs) dgr1.EditItemIndex = -1 BindData End Sub Edited January 10, 2006 by PlausiblyDamp Quote
kahlua001 Posted January 20, 2005 Posted January 20, 2005 Becuase you created your dataset inside a sub, it only exists in that sub. So upon postback, it no longer exists, you need to recreate it. Or, you could load the dataset in a viewstate or session variable, then on postback the persisted data would be available to you again. Quote
paulhudson Posted January 20, 2005 Author Posted January 20, 2005 (edited) acceptchanges to dataset I have now used session state to hold the dataset. So now the dataset is displayed in edit mode ok. But on selecting update the dataset has no changes applied. No errors occur. Sub DoItemEdit(ByVal Sender As Object, ByVal E As DataGridCommandEventArgs) dgr1.EditItemIndex = CInt(E.Item.ItemIndex) Dim tpDataSet As New DataSet() tpDataSet = Session("tpDataSet") dgr1.DataSource = tpDataSet.Tables("TeamPlayers") dgr1.DataBind() End Sub Sub DoItemUpdate(ByVal sender As Object, ByVal e As DataGridCommandEventArgs) Dim tpDataSet As New DataSet() tpDataSet = Session("tpDataSet") tpDataSet.AcceptChanges() dgr1.DataSource = tpDataSet.Tables("TeamPlayers") dgr1.DataBind() End Sub Edited January 10, 2006 by PlausiblyDamp Quote
kahlua001 Posted January 20, 2005 Posted January 20, 2005 After you update your dataset, do you reset the session variable with your new dataset? 'Updating dataset Session("Dataset") = MyDataset Also..it might be better to create a page level dataset variable and in your page_load, grab it from your session or create it. Private myDataset as dataset Private sub page_load(e as .., s as..) If Not IsPostBack Then 'First time to this page, create the dataset myDataset = new dataset Session("myDataSet") = myDataset Else 'Posting back, dataset already exists, grab from session myDataset = session("myDataSet") End If End Sub Then in your datagrtid events, just make sure you reset the session with the new dataset. Quote
paulhudson Posted January 21, 2005 Author Posted January 21, 2005 (edited) acceptchanges to dataset I have done as suggested with the page load, and I have posted my update script below. I call the acceptchanges, then refresh the session with the dataset and then bind the datagrid to the same dataset - but no changes are shown. Code: Sub DoItemUpdate(ByVal sender As Object, ByVal e As DataGridCommandEventArgs) tpDataSet.AcceptChanges() Session("tpDataSet") = tpDataSet dgr1.EditItemIndex = -1 dgr1.DataSource = tpDataSet.Tables("TeamPlayers") dgr1.DataBind() Edited January 10, 2006 by PlausiblyDamp Quote
paulhudson Posted January 21, 2005 Author Posted January 21, 2005 (edited) Ok, so I have been a bit dippy on this one. When leaving edit mode of datagrid, I need to extract the new values and modify the relevant row in the dataset. I've got this far, with one slight problem. When I try to find the row using a uniqueID I get an error message: Input string was not in a correct format The column is created thus: tpDataColumn = New DataColumn() tpDataColumn.DataType = System.Type.GetType("System.Int32") tpDataColumn.ColumnName = "UniqueID" tpDataColumn.ReadOnly = True tpDataColumn.Unique = True tpDataColumn.AutoIncrement = True And the find command is (error on last line): Dim KeyID As Integer KeyID = CType(e.Item.FindControl("UniqueID"), Label).Text Dim foundRow As DataRow foundRow = dtTeamPlayers.Rows.Find("KeyID") Could this be something to do with the auto-increment feature? Edited January 10, 2006 by PlausiblyDamp Quote
kahlua001 Posted January 21, 2005 Posted January 21, 2005 foundRow = dtTeamPlayers.Rows.Find("KeyID") I think you mean foundRow = dtTeamPlayers.Rows.Find(KeyID) Quote
paulhudson Posted January 22, 2005 Author Posted January 22, 2005 Excellent - just what was missing. It all works now - thanks for all your help kahlua001! Quote
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.