Disconnected dataset -- can't delete row???

R

Rob Perkins

The following code snipped is intended to delete a row from a typed
dataset. The name of the dataset instance is "dbMats", which contains a
table called "CastingAlloys". Instead of deleting the row it is actually
moving the row to be the first item in the dataset's "CastingAlloys"
table.

I haven't been able to figure out why.

The UI for the dataset is a ListBox, with the DataSource property of the
ListBox set to the "CastingAlloys" table in the dataset. The
DisplayMember and ValueMember properties are likewise bound to fields in
the table.

When a user clicks on one of the ListBox items, a subroutine is called
which *copies* the database values from the selected row into a separate
data structure, which is in turn bound to other UI elements on the form.
There is no further interaction between those UI elements and the
ListBox. (They are view-only elements)

I'm making use of the MSDataSetGenerator-generated method,
"RemoveCastingAlloysRow", and can't figure out why the row doesn't
actually *get removed*.

Any ideas?
Dim r As dbMats.CastingAlloysRow
Try
r = CType(CType(lstdbCastingMats.SelectedItem, DataRowView).Row, dbMats.CastingAlloysRow)
Try
lstdbCastingMats.SelectedIndex = lstdbCastingMats.SelectedIndex + 1
Catch ex As Exception
lstdbCastingMats.SelectedIndex = 0
End Try
ds.CastingAlloys.RemoveCastingAlloysRow(r)
'CType(lstdbCastingMats.SelectedItem, DataRowView).Delete()
Catch ex As Exception
MsgBox(ex.ToString)
End Try

Rob
 
M

Miha Markic [MVP C#]

Use Delete instead of Remove.
Delete marks row as deleted while Remove vaporizes its presence in dataset
and dataadapter misses it.
 
R

Rob Perkins

Miha said:
Use Delete instead of Remove.
Delete marks row as deleted while Remove vaporizes its presence in dataset
and dataadapter misses it.

well...

It's a file-based dataset. I just designed a schema and I read and write
the XML using ReadXML etc, so there is no dataadapter connected.

Rob
 
C

Cor Ligthert [MVP]

Rob,

Can it be a relation, where you try to remove the parent which has still
childs?

Cor
 
R

Rob Perkins

Cor said:
Rob,

Can it be a relation, where you try to remove the parent which has still
childs?

There is no formal relation defined in the schema. If I drop this
dataset onto a DataView, and navigate to the table, select a record row
and tap the delete key, then the record deletes. From there I can just
save the XML file out again with WriteXML, without trouble.

But, I can't seem to duplicate that behavior with what
ListBox.SelectedItem returns.

And perhaps I misused "disconnected", by which I meant that there is no
associated DataAdapter with this dataset. I just read in an XML file,
present it to the user for viewing through a ListBox control which has
the DataSource, DisplayMember, and ValueMember properties defined into
the dataset, and which is supposed to allow the deletion of whole records.

I'm sincerely and completely stumped by this.

Rob
 
C

Cor Ligthert [MVP]

Rob,

The remove should remove the row.

You can do the behaviour of the dataadapter with the
ds.acceptchanges, however I have not the idea that that is the issue.

That is accoording to deleted rows.

We cannot see what that remove method is inside your strongly typed dataset,
it is always hard to find a problem with a strongly typed dataset.

Can you try it as a non strongly typed dataset

ds.tables("CastingAlloys").Rows.Remove(TheDataRow)

http://msdn2.microsoft.com/en-us/library/system.data.datarowcollection.remove.aspx

I hope this helps,

Cor
 
R

Rob Perkins

(Changed identity headers to hopefully get the attention of MS)
We cannot see what that remove method is inside your strongly typed dataset,
it is always hard to find a problem with a strongly typed dataset.

The MSDataSetGenerator generated code looks like this:

Public Sub RemoveCastingAlloysRow(ByVal row As CastingAlloysRow)
Me.Rows.Remove(row)
End Sub


....where the "Rows" member is nothing more than a DataRowCollection
inherited from the DataTable type.
Can you try it as a non strongly typed dataset

ds.tables("CastingAlloys").Rows.Remove(TheDataRow)

I tried this:

r = CType(CType(ListBox1.SelectedItem, DataRowView).Row, DataRow)
ds.tables("CastingAlloys").Rows.Remove(r)

The result is that the row to be removed appears either to be removed
and then reinserted at the top of the datatable, or simply appears to be
moved to the top of the list.

I have a DataGrid in a separate window watching this happen as well; the
problem is happening to the DataSet, it's not an artifact of the UI that
I can see.

The schema backing the generated classes is likewise not complex. It
consists simply of three unrelated table definitions, whose columns
contain only strings, floats, and ints.

Still completely without an explanation as to why it behaves *this* way,
and getting more frustrated and not a little emotionally involved...

By everything I can read in the documentation at MSDN, this should work
without errors. I'm on the verge of calling it "crap" and railing
against MS, since I went down this road with years of assurance that
moving to ADO.NET instead of sticking to DAO or ADO would be "better".
Instead I get unexplained and apparantly unexplainable side effects, and
a hand out for $300 if I want MS to take a close look.

And, of course, that ripping it out and hand-rolling something would
take weeks I now don't have in our product cycle. Thanks a ton, MS. I'm
angry now.

Rob
 
C

Cor Ligthert [MVP]

Rob,

I have made this simple piece of code and tested it in VS2003 and VS2005

The result was that row 10 is not in the datagrid, can you give me an idea
where it is essential not the same as your code?

\\\
Private Sub Form1_Load(ByVal sender As System.Object, _
ByVal e As System.EventArgs) Handles MyBase.Load
Dim dt As New DataTable
dt.Columns.Add("MyColumn")
For i As Integer = 0 To 19
dt.LoadDataRow(New Object() {i.ToString}, True)
Next
Dim dr As DataRow = dt.Rows(10)
dt.Rows.Remove(dr)
DataGrid1.DataSource = dt
End Sub
///

Cor
 
R

Rob Perkins

Cor said:
Rob,

I have made this simple piece of code and tested it in VS2003 and VS2005

The result was that row 10 is not in the datagrid, can you give me an idea
where it is essential not the same as your code?

The difference is that the row in question is referenced by the ListBox
control, whose "SelectedItem" property comes back with a DataRowView
object, from which I extracted the row I'm using to delete.

However, I've also tried deleting the row found by searching the
DataTable using a key value found in both the DataRowView and the row in
the table I want to delete, with identical results.

Well, I've taken now to removing the XSD from the project altogether and
hacking at the VB file the MSDataSetGenerator created, by backing it up
and adding it as though it were a hand-written thing from the backup.

So I'll see what happens, step by step here, after removing the
debuggerstepthroughattribute from all these classes.

Rob
 
R

Rob Perkins

Rob said:
So I'll see what happens, step by step here, after removing the
debuggerstepthroughattribute from all these classes.

I took the same XML file and created a test project using ListView and a
generic dataset. It worked.

So I added the typed dataset to the test project, which also worked.

So, here's another thought. My form class binds *other* controls on the
form to this dataset's CastingAlloys table, as follows:

Me.txtName.DataBindings.Add(New System.Windows.Forms.Binding("Text",
Me.ds.CastingAlloys, "AlloyName"))

(there are other bindings onto columns of that table)

....the whole point being that a user who clicks in the list can see
other details related to the selection in text boxes and such.

Could *that* be the source of my side effect?

Rob
 
R

Rob Perkins

Rob said:
So, here's another thought. My form class binds *other* controls on the
form to this dataset's CastingAlloys table, as follows:

Me.txtName.DataBindings.Add(New System.Windows.Forms.Binding("Text",
Me.ds.CastingAlloys, "AlloyName"))

(there are other bindings onto columns of that table)

...the whole point being that a user who clicks in the list can see
other details related to the selection in text boxes and such.

Could *that* be the source of my side effect?

Trying that in my test project, I find that it is not the cause of the
side effect.

I'm still completely lost.

Rob
 
C

Cor Ligthert [MVP]

Rob,

Reading your replies, I got the idea that a not so nice however normal side
effect from the listcontrols (listbox and combobox) is that if you change a
selected item in those events. They start to work recursevily and give
mostly unpredictable results. I cannot see your code, however if it can be
that than you can change that by setting the event trapping in advance off
at the start and add it again at the end.

Remove.handler listbox1.indexchanged, addressof myclickevent


Addhandler and than the same.

I hope this helps,

Cor
 
R

Rob Perkins

Cor said:
Rob,

Reading your replies, I got the idea that a not so nice however normal side
effect from the listcontrols (listbox and combobox) is that if you change a
selected item in those events. They start to work recursevily and give
mostly unpredictable results.

I began to think along those lines. I do in fact hook
ListBox.SelectedIndexChanged, in order to compute some related data and
plot some graphics.

My thought was that perhaps there was some multithreading issue at work.
I cannot see your code, however if it can be
that than you can change that by setting the event trapping in advance off
at the start and add it again at the end.

Remove.handler listbox1.indexchanged, addressof myclickevent

Trying this, I find that the behavior is the same. I think I'll try a
flag variable...

Rob
 
R

Rob Perkins

Rob said:
Trying this, I find that the behavior is the same. I think I'll try a
flag variable...

Still completely stumped. The flag variable didn't work. *Removing the
SelectedIndexChanged event handler altogether* didn't work.

I gave up. Did this instead:
Dim newds As New dbMats
newds.ReadXml(VB6.GetPath & "\Alloy Database.xml")
r = newds.CastingAlloys.FindByAlloyName(lstdbCastingMats.SelectedValue)
r.Delete()
newds.WriteXml(VB6.GetPath & "\Alloy Database.xml", XmlWriteMode.WriteSchema)
ds = newds
lstdbCastingMats.DataSource = Nothing
lstdbCastingMats.DataSource = newds.CastingAlloys
lstdbCastingMats.DisplayMember = "AlloyName"
lstdbCastingMats.ValueMember = "AlloyName"
lstdbCastingMats.SelectedIndex = savedindex

....all in a Try block to catch range errors and lookup failures.

Rob
 

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

Top