Advertisement

Silverlight DataForm and confirming deleting an item

I was talking with a good friend the other day about some feedback about DataForm.  It’s great to get raw and honest feedback…that’s where you improve more than ‘it sucks’ type feedback.  One of the use cases he felt would be common with the Silverlight DataForm control (available in the Silverlight Toolkit) was the concept of confirming the delete action.  I agreed as well that confirming permanent delete actions is a common line-of-business application pattern.  It got me thinking about some things…

The Problem

DataForm is a great control.  I love it.  It will benefit many developers in the simplest applications quickly as well as some in the most complex applications with some additional configuration.  For the purposes of this demonstration, I’ll talk about the simplest scenario.  DataForm has build in controls for navigating a bound data set, as well as adding and deleting new items.  It is the deleting I’d like to concentrate on here. 

When DeleteItem is called on DataForm (via the built-in toolbar or via your own methods), it deletes the current item.  After all, that’s what you told it to do!  The problem is that the delete is fast and there is no easy “undo” method. 

The Helper

Luckily, DataForm provides a method interceptor for us: DeletingItem.  This event fires when DeleteItem is called and tells you: Hey, I’m about to delete the current item.  If you want to do anything about that, now is the time.  So there you have it…you can prevent the delete because there is a CancelEventArgs parameter passed in to cancel the remaining event.  So what would you do in DeletingItem?

Solution 1: Go modal

One thing you can do is leverage a modal dialog.  This would block the event until a modal dialog response is provided for you to investigate.  Here’s an example of what you might do in DeletingItem:

   1: private void PeopleBrowser_DeletingItem(object sender, System.ComponentModel.CancelEventArgs e)
   2: {
   3:     if (MessageBox.Show("Are you sure you want to delete this item?\nThis cannot be undone", "Delete Item", MessageBoxButton.OKCancel) == MessageBoxResult.Cancel)
   4:     {
   5:         e.Cancel = true;
   6:     }
   7: }

So what’s the problem with this one?  Nothing really.  The dialog would show, giving your user a chance to react and block the delete call until an OK is received (it cancels the event if Cancel is clicked).  But let’s look what it generates from a user experience standpoint:

confirm delete with MessageBox

Hmm, maybe there is a problem.  First, it says OK or Cancel…not really a “Yes or No” response the user is really looking for.  Second, using MessageBox will focus the dialog in the center of your window and not center of parent (or calling control).  These two things make it less ideal in my opinion.  The major positive here is twofold: it works and it’s truly modal (thus blocking the call to delete).

Solution 2: Pimp your dialog, but also your code

Silverlight is all about improving the user experience right?  Changing things around and differentiating the RIA?  So let’s use that mantra to think what we could do here.  Silverlight 3 provides a new control, ChildWindow that you could use in this instance.  It provides a modal-like experience to the end user (blocking other UI components) and gives them a focused area to provide a response.

NOTE: I’ve refactored ChildWindow into something I call “FloatableWindow” for MDI or other type interfaces.  I’ve provided my code for you to use on the .  I’ve also added a work item on the Silverlight Toolkit so if you like the idea, please vote on it!

The challenge with ChildWindow is that while it exhibits all the UI experience of a modal dialog, behind the scenes it is asynchronous.  This means that if you put a Show() call to a ChildWindow in your code, that your next line of code will run as well.

NOTE: If you think this should be changed, consider voting on the Silverlight Toolkit project for this item: ChildWindow – make it modal.

We can, however, still be creative.  Let’s explore an idea here.  We know that we have the DeletingItem event we can still tap into, so we can trigger our implemented ChildWindow like this:

   1: private void PeopleBrowser_DeletingItem(object sender, System.ComponentModel.CancelEventArgs e)
   2: {
   3:     ConfirmDialog cd = new ConfirmDialog();
   4:     cd.Show();
   5: }

The problem is that unless we cancel the event, the delete will still happen (and you can see it happen from behind the ChildWindow even…frustrating!  The ChildWindow.DialogResult is essentially worthless to us right now.  Let’s think creatively though.  What I did was create a member variable called _delete and set it to false.  This tells the DeletingItem event whether or not it really should delete.  It sounds dumb, I know, but work with me.

Now when we call DeletingItem, we check to see if we really should delete or not (really we check to see if we should cancel the event).  If we are still in “false” mode, then we shouldn’t delete but should show our confirmation window and cancel the DeletingItem event.  That’s great, but we still need to get the user response from the window!  We then need to tap into the ChildWindow.Closed event and get the DialogResult from there.  In the Closed event we can see if they confirmed the delete.  If they cancelled the delete, we do nothing further.  If they said “Yes” then we need to change our _delete variable and call DeleteItem on our DataForm again.  Now our DeletingItem handler knows we can successfully continue.

Sound fuzzy?  Sound like a hack?  Maybe so, but it works.  This gives us the opportunity to create a customized user experience for the confirmation.  Now I’m a crappy designer, but to make the point clear to differntiate from simple MessageBox, my ChildWindow has a flashing background and blurs the DataForm.  Yeah, it’s obnoxious, but that is the point for this demonstration!  Here’s the complete code for this solution:

   1: private bool _delete = false;
   2:  
   3: private void PeopleBrowser_DeletingItem(object sender, System.ComponentModel.CancelEventArgs e)
   4: {
   5:     if (!_delete)
   6:     {
   7:         Person p = PeopleBrowser.CurrentItem as Person;
   8:         ConfirmDialog cd = new ConfirmDialog();
   9:         cd.Closed += new EventHandler(cd_Closed);
  10:         cd.Title = string.Format("Delete {0} {1}?", p.FirstName, p.LastName);
  11:         BlurEffect b = new BlurEffect();
  12:         b.Radius = 10;
  13:         PeopleBrowser.Effect = b;
  14:         cd.Show();
  15:         e.Cancel = true;
  16:     }
  17:     else
  18:     {
  19:         _delete = false;
  20:     }
  21: }
  22:  
  23: void cd_Closed(object sender, EventArgs e)
  24: {
  25:     PeopleBrowser.Effect = null;
  26:     ConfirmDialog cd = sender as ConfirmDialog;
  27:     if (cd.DialogResult == true)
  28:     {
  29:         _delete = true;
  30:         PeopleBrowser.DeleteItem();
  31:     }
  32: }

You can try this out yourself here (requires Siliverlight 3): Sample confirm delete with DataForm.  Go ahead, I’ll wait. 

Obnoxious isn’t it :-).  Of course using Expression Blend to customize your own is highly recommended!

Summary

While there is no true modal dialog in Silverlight other than MessageBox (which isn’t XAML-customizable), these are two options that provide you with the opportunity to confirm your delete action within DataForm.  Hopefully these are helpful to get you to think at least and if someone has better implementations, please share them!  You can download the complete code for this sample here: ConfirmDeleteDataForm.zip

Hope this helps!


This work is licensed under a Creative Commons Attribution By license.

  1. 8/7/2009 4:05 PM | # re: Silverlight DataForm and confirming deleting an item
    Hi Tim;

    Thanks for info. I hope that becomes built in especially when you have an app that has 100+ forms.

    But as far as using a Modal MessageBox, ComponentOne has a great "MessageBox" that gives you options for: Ok, OkCancel, YesNo, YesNoCance buttons. So, for this case we can select YesNo and we can also place it anywhere and add a "Warning" Icon too.
  2. 8/7/2009 4:13 PM | # re: Silverlight DataForm and confirming deleting an item
    Ben is theirs truly modal and blocks calls?
  3. 8/7/2009 4:18 PM | # re: Silverlight DataForm and confirming deleting an item
    I will confirm that and get back to you!
  4. 8/7/2009 5:12 PM | # re: Silverlight DataForm and confirming deleting an item
    Hi Tim,

    If you click on the link to the toolkit, and then select DataForm, it redirects you to a page with no DataForm information. What exactly does the DataForm do? And as far as ComponentOne's MessageBox, I don't see how it could possibly be modal without the framework supporting modal operations natively (which it doesn't)
  5. 8/7/2009 5:16 PM | # re: Silverlight DataForm and confirming deleting an item
    Hi Jack, the DataForm is like a DetailsView in ASPNET. If that doesn't help :-), it can accept a binding to an object and displays the edit form for you (automatically creates the labels, edit boxes). Of course you can customize it how you like, but in the simplest form that's it. In this example, if you look at the code you'll see i have <dataform:DataForm> in the XAML and no other information. I bind my Person object to it and it creates the form for me.
  6. 8/8/2009 2:26 PM | # re: Silverlight DataForm and confirming deleting an item
    Hi Ben, Tim & Jack,

    I am from ComponentOne :)

    Blocking the .Show() method is not possible with C1MessageBox.

    We do expose a callback method to know when the C1ModalDialog was close, but you still have the problem Tim is explaining here, and some kind of "hacky" workaround is required.

    Regards
  7. 8/9/2009 11:36 AM | # re: Silverlight DataForm and confirming deleting an item
    Tim, I just ran your sample and noticed you forgot one thing when MessageBox pops up. You forgot the "siren" :-)
  8. 8/9/2009 11:56 AM | # re: Silverlight DataForm and confirming deleting an item
    Ben - nice! THat would be added obnoxiousness ;-)
  9. 8/9/2009 12:35 PM | # re: Silverlight DataForm and confirming deleting an item
    Tim ... nice post on calling out this issue. I did a similar hack to get around this problem. I hope more people vote up the modality of the ChildWindow for a future revision. This is just one of several modality issues I have run into, so it would be great to have an option better than one of my "hacks" :)
  10. 8/9/2009 10:22 PM | # re: Silverlight DataForm and confirming deleting an item
    Umm, I don't consider this a hack *except* for where the delete is performed. Just like any recursive operation can be converted to a non-recursive one and vice-versa, every synchronous operation can be converted to an asynchronous one and vice-versa. Mechanisms common to these conversions (where the "normal" operation might not need these) might look like hacks but are intrinsic to the conversion. One article I refer to from time to time is www.csharp411.com/convert-between-synchronous-a....

    In this case I'd vote for allowing the ChildWindow .Show operation to be made synchronous (calling it like .Show(true) as an overloaded function). Also, while I'm not familiar with the technology in the first-hand sense of the word, Rx might allow for a simpler mechanism to do this: themechanicalbride.blogspot.com/.../...events.html
  11. 8/12/2009 1:28 AM | # re: Silverlight DataForm and confirming deleting an item
    Nice post :)
    But having 95% CPU load while showing the popup window is not so nice ^^
  12. 8/12/2009 2:17 AM | # re: Silverlight DataForm and confirming deleting an item
    Hi Tim,

    Could you explain the OK and Cancel buttons at the bottom of the Silverlight App?

    Delete confirmation is an obvious scenario but there are two scenarios that are just as common and useful: Undo and Cancel. These require a lot more thinking and planning...
  13. 8/12/2009 2:50 AM | # re: Silverlight DataForm and confirming deleting an item
    Tim,
    Users have cryptographic devices (eToken) with digital certificate.
    How integrate Silverlight 3 with signing dataform functionality?
    Thx, Andrzej
  14. 8/12/2009 9:54 AM | # re: Silverlight DataForm and confirming deleting an item
    mbr123 - sorry ;-)

    Erno - those are default command buttons for DataForm OK = save, Cancel = Undo changes

    Andrzej - I'm confused what you want here? Interaction with client certificates? Not possible directly.
  15. 8/21/2009 11:23 PM | # re: Silverlight DataForm and confirming deleting an item
    hi tim
    plz ask how to add a row in datagrid in silverlight application with ria service
    ???????

 
Please add 4 and 1 and type the answer here:
First time here? You are looking at the most recent posts. You may also want to check out older archives. Please leave a comment, ask a question and consider subscribing to the latest posts via RSS or email. Thank you for visiting! (hide this)