Cancelling Row deletion in DataGrid (forms NOT ASP.NET)

M

Mortos

Hi Gurus,
This has been doing my head in so I've come the you guys.
I have 2 DataGrids using a DataViewManager to source their data. They
are linked via a DataRelation which basically creates a Parent-Child
relation between the 2 grids.

Now I would like to prevent the deletion of any parent row that has
child rows. I have gone down the route of using a 'ForeinKeyConstraint'.
(For all the good that did.) Any I set the DeleteRule to 'None' to stop
said deletion. However, I kept on getting an 'untrappable' exception
(InvalidConstraintException) that always brought everything down
whenever a parent row is deleted.

OK plan B. Forget the use of constraints. Let's do it manually. So i set
up a RowDeleted event (This does not run on the RowDeleting event.) on
the underlying DataTable of the parent grid and try
"e.Row.RejectChanges()" from there and it seems to work except one
problem. The DataGrid is not showing the 'undeleted' (or rejected) row
so I need to force the refreshing of the 'CurrencyManager' as in

//(tgtGrid = TargetDataGrid)
CurrencyManager currMgr =
(CurrencyManager)this.BindingContext[tgtGrid.DataSource,
tgtGrid.DataMember];
currMgr.Refresh();

When run from a 'Refresh' button all rows are displayed. However, I want
the 'Grid Refresh' done 'automagically' when the row delete is aborted
in code.

Any Ideas people? I can't really dedicate more time to finishing the
module until I know there is light at the end of this tunnel ;-)
 
C

Christian Kuendig

Try to call EndEdit after undeleting the row... let me know if it worked.

regards

Chris
 
D

Dave L

I have the same problem.

I just did a Google search on "RowDeleting event" in
microsoft.public.dotnet.* and got 5 pages worth of people complaining
about the same problem.

The best solution appears to be to subclass your "parent" DataGrid,
override ProcessCmdKey, and validate the delete there.

I tried Christian's EndEdit and that didn't work.

Hope that helps...

Dave

Christian Kuendig said:
Try to call EndEdit after undeleting the row... let me know if it worked.

regards

Chris

Mortos said:
Hi Gurus,
This has been doing my head in so I've come the you guys.
I have 2 DataGrids using a DataViewManager to source their data. They
are linked via a DataRelation which basically creates a Parent-Child
relation between the 2 grids.

Now I would like to prevent the deletion of any parent row that has
child rows. I have gone down the route of using a 'ForeinKeyConstraint'.
(For all the good that did.) Any I set the DeleteRule to 'None' to stop
said deletion. However, I kept on getting an 'untrappable' exception
(InvalidConstraintException) that always brought everything down
whenever a parent row is deleted.

OK plan B. Forget the use of constraints. Let's do it manually. So i set
up a RowDeleted event (This does not run on the RowDeleting event.) on
the underlying DataTable of the parent grid and try
"e.Row.RejectChanges()" from there and it seems to work except one
problem. The DataGrid is not showing the 'undeleted' (or rejected) row
so I need to force the refreshing of the 'CurrencyManager' as in

//(tgtGrid = TargetDataGrid)
CurrencyManager currMgr =
(CurrencyManager)this.BindingContext[tgtGrid.DataSource,
tgtGrid.DataMember];
currMgr.Refresh();

When run from a 'Refresh' button all rows are displayed. However, I want
the 'Grid Refresh' done 'automagically' when the row delete is aborted
in code.

Any Ideas people? I can't really dedicate more time to finishing the
module until I know there is light at the end of this tunnel ;-)
 
M

Mortos

Yeah I saw that page myself. I do wish the MS employee had gotten back
to the list!!! I 'solved' it via another route. Using the 'RowDeleted'
method and refreshing the grid via a seperate thread. (Yeah I know but
subclassing the grid for this and checking for the delete key is
just...). This works because the RowStatus has been set to unchanged at
this point so a different thread *will* see the Row.Status as 'unchanged'.

So basically after calling 'Row.RejectChanges()' in the 'RowDeleting'
event, you start another thread that will refresh the grid's
CurrencyManager. You can also set a slight delay in the method ran by
'Thread.Start()' (Time.Sleep(50) for instance?) just to make sure. This
works for me ;-)


Dave said:
I have the same problem.

I just did a Google search on "RowDeleting event" in
microsoft.public.dotnet.* and got 5 pages worth of people complaining
about the same problem.

The best solution appears to be to subclass your "parent" DataGrid,
override ProcessCmdKey, and validate the delete there.

I tried Christian's EndEdit and that didn't work.

Hope that helps...

Dave
{Snip}
 
D

Dave L

Having just completed implementing the ProcessCmdKey override, I found
2 gotcha's that you must pay attention to:

1) You need to trap ALT-DELETE as well as DELETE
2) You need to check that the focus is on the row, not in one of the
datagrid's fields.

Here's my code (apologies for the Managed C++) for the complete
solution:

public __gc class DeleteConfirmDataGrid : public DataGrid
{
protected:
bool ProcessCmdKey(Message* msg, Keys keys)
{
if (((keys & Keys::KeyCode) == Keys::Delete))
{
if ((msg->Msg == WM_KEYDOWN) ||
((msg->Msg == WM_SYSKEYDOWN) && (this->ModifierKeys ==
Keys::Alt)))
{
if (this->Focused)
{
if (business logic decides that the row should NOT be deleted)
{
return true;
}
}
}
}

return DataGrid::processCmdKey(msg, keys);
}
};


Dave L wrote in message news: said:
I have the same problem.

I just did a Google search on "RowDeleting event" in
microsoft.public.dotnet.* and got 5 pages worth of people complaining
about the same problem.

The best solution appears to be to subclass your "parent" DataGrid,
override ProcessCmdKey, and validate the delete there.

I tried Christian's EndEdit and that didn't work.

Hope that helps...

Dave

Christian Kuendig said:
Try to call EndEdit after undeleting the row... let me know if it worked.

regards

Chris

Mortos said:
Hi Gurus,
This has been doing my head in so I've come the you guys.
I have 2 DataGrids using a DataViewManager to source their data. They
are linked via a DataRelation which basically creates a Parent-Child
relation between the 2 grids.

Now I would like to prevent the deletion of any parent row that has
child rows. I have gone down the route of using a 'ForeinKeyConstraint'.
(For all the good that did.) Any I set the DeleteRule to 'None' to stop
said deletion. However, I kept on getting an 'untrappable' exception
(InvalidConstraintException) that always brought everything down
whenever a parent row is deleted.

OK plan B. Forget the use of constraints. Let's do it manually. So i set
up a RowDeleted event (This does not run on the RowDeleting event.) on
the underlying DataTable of the parent grid and try
"e.Row.RejectChanges()" from there and it seems to work except one
problem. The DataGrid is not showing the 'undeleted' (or rejected) row
so I need to force the refreshing of the 'CurrencyManager' as in

//(tgtGrid = TargetDataGrid)
CurrencyManager currMgr =
(CurrencyManager)this.BindingContext[tgtGrid.DataSource,
tgtGrid.DataMember];
currMgr.Refresh();

When run from a 'Refresh' button all rows are displayed. However, I want
the 'Grid Refresh' done 'automagically' when the row delete is aborted
in code.

Any Ideas people? I can't really dedicate more time to finishing the
module until I know there is light at the end of this tunnel ;-)
 

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