|
So how do we deal with this problem? There are a few alternatives available to us. One of
the choices we have is to use an INSTEAD OF trigger in the backend database. But hey, the
purpose here is to figure out how to make Iron Speed Designer do its stuff right? Let’s look
at one way we can deal with this issue entirely in Iron Speed Designer by adding a few lines of
code to the safe class behind our Show Table page and setting an attribute on the Delete button
itself.
While trying to resolve this issue in an application I recently completed (and, yes, all
through development I just assumed the delete button worked!), I started poking around in
the Iron Speed Designer-generated classes. Now as many of you already know, this in itself
is no small task as there are a lot of those puppies in there! So where do we start?
Let’s start by looking at the application documentation Iron Speed Designer generates (not
the Base Classes documentation). We are looking for the class that represents the table from
which we are trying to delete a record. In our example, this is the Expenses table (see Query
Listing 1 above) as our Show Table page is connected to our vwExpenseDetailReport view which
primarily pulls from the Expenses table in our database.
Working our way down the tree of class objects in the documentation, we come across an entry
called "BaseExpensesTable Class". Bingo! Even better, when we expand that tree node and expand
the Methods node, we find a method called "DeleteRecords". Man it's like those Iron Speed engineers
have thought of everything!
So now we know that our table class has a delete records method. Looking at the documentation
we find this method deletes records using a where clause. Hmmm…if we passed to this method [in
the where clause] the primary key of the record we want to delete we should be home free.
Can it be this easy? The answer of course is “Yes” – it is that easy. But how do we employ this
DeleteRecord method? As you probably know, .NET is all about objects, properties, methods
and...events! If we trap the right event and call the DeleteRecords method on our Expenses table
that should do the trick. How can we capture an event? By overriding the OnApplicationEvent method.
Opening up Help in Iron Speed Designer and searching for "override event" we get several hits.
Looking at the topic, "Overriding the DeleteRecord event", we learn that we can override the
DeleteRecord event in the TableControl class. The example given in Help looks like:
Now we are getting somewhere! Let’s open up the safe class behind our Show Table page and see
if we can modify this example from Iron Speed Designer Help to work for us.
What we are looking for is the proper place to insert some code in our safe class. The Iron Speed
Designer Help topic told us that the place we want to override the DeleteRecord event is in the TableControl
class. In my application, this is in the ApplicationName.PanelControls.ShowVwExpensesTablePage namespace and
looks like this:
Now all we need to do is trap the delete record event and run our own code instead of the
Iron Speed Designer-generated DeleteRecord event. Remember, we are displaying a view but we
need to delete the record from the underlying Expenses table the view draws from. Here I will
show you the code you need to insert into the TableControl class to delete a record from a table
and not from the view itself. Then we will walk through the code line by line and see how it all
works.
Now let’s go into detail in the code and see exactly what is going on here:
This line tells .NET that we are running the code that follows instead of the code that
.NET would normally run for a given event.
Next we set up an if…else conditional test to check the event that is being processed.
If the event type is DeleteRecord, we want to run our own code in place of Iron Speed’s
regular DeleteRecord method which, of course, would run against our view and generate an
error. We do this with the following line of code:
If the event being processed is the DeleteRecord event then we need to get the primary key
value of the SELECTED record in the table control. How can we do this? If we turn once again
to Iron Speed Designer Help and search for "selected row" we get several hits. Our luck is holding
up well here as one of the topics is titled, "Handling the Selected Row in a Table". In that example
we see the line below does just that for us:
Okay now we have a handle to the row in our table control that the user selected. Now we just
need to get the primary key column value for that row so we can pass it in the where clause of
our DeleteRecord method. Here we need to remember that we are deleting a record from the Expenses
table but the selectedComponent object variable in our code is pointing to a record in the VwExpenses
view. So what we will do is get a record object and fill it with data from the selected row via the
GetRecordData method of the IRecordComponent class object as so, passing in an argument value of false since
we can get by fine with a read-only record…
If we have the actual data values of the selected row from our table control in a record
object, all we need now is the primary key value so we can build our where clause. We can
do this by referencing the ExpenseKey column of our record object, converting that value to
a string with the ToString() method of the column and then converting to an integer that we
can pass in our where clause. The line of code below does just this -
Okay, now that we have the primary key value of the selected row we can call the
DeleteRecords method on the Expenses table and actually delete the record the user
selected in the table control. The where clause we will use simply references the primary
key column of the Expenses table.
We are almost home now. Since it is not politically correct (or good programming practice) to
leave any transactions open, we need to commit the transaction that the Iron Speed Designer-generated
application opened behind the scenes for us to delete the record. To do this, call the CommitTransaction
method of the SystemUtils class and pass a value of true for the ‘autoRollback’ argument:
That’s it! Our record is deleted. But where do we go now? Most likely the user will want to
see the show table page so she can verify the record was deleted. However if we post back to
the page itself we need to make sure the data is refreshed otherwise our deleted record will
still show in the cached output. To fix this we do a redirect to our show table page so the page
loads with current data.
However if we stop here we have a problem! What about all those page and control events
that aren’t of the type DeleteRecord? We need to allow those to complete in a normal fashion.
To this end we use the code below:
Now we have successfully handled the DeleteRecord event without interfering with any
other events that may be generated by the page or its child controls. Close the if...else
conditional test and the application event override function and we are done. Rebuild the
application to compile our code and we are all good.
To add a nice extra touch to our application, let’s save our users the grief of clicking
Delete only to find they had selected the wrong record. To accomplish this, switch to Design
view for the Show Table page and open the page properties dialog. Select the Delete button and
go to the Attributes tab. On that tab enter the following attribute name and value –
This tells the Iron Speed Designer-generated application that when a user clicks the
delete button we want to pop up a message box and give them a chance to confirm the
transaction by clicking “Okay” or back out of it by clicking "Cancel".
|