Handling the OK Button Click

Handling the OK Button Click

Old forum URL: forums.lhotka.net/forums/t/3174.aspx


josh.kodroff posted on Wednesday, July 11, 2007

I'm a little shaky on the best way to handle the click event of an OK button in order to provide a good user experience.

Using the code from the book, it would appear that if the object is not in a valid state and can't be saved, an exception will be thrown, the user will receive an error, and the form will close without saving.  Obviously this is not desired behavior.

I've considered binding the OK button's Enabled property to the object's IsValid property, but because databinding updates only occur after a field's control is exited, the OK button won't immediately become enabled, and that's very awkward from a UI standpoint.

I'm sure this is a problem that's been solved a million times over, so what's the optimal solution?

hurcane replied on Wednesday, July 11, 2007

You don't have to allow the exception to be raised if the user clicks OK when the object is not valid. Check for it and show a simple message box when handling the click event on the button. You could even show the broken rules in the dialog. This avoids the awkwardness of enabling/disabling the button.

VoodooSV replied on Thursday, July 12, 2007

Additional you can use ErrorProvider if you set validation rules to your object. In this case user can see information why the object is in invalid state.

ajj3085 replied on Thursday, July 12, 2007

You can do what you want (tie the buttons Enabled to IsSavable) if you go into the Advanced data binding settings and set the property to update on Property Change,instead of Validation.

ozitraveller replied on Thursday, July 12, 2007

Could you explain a bit further about binding the Enabled property to IsSavable. IsSavable doesn't show in my list.

Thanks

tetranz replied on Thursday, July 12, 2007

ozitraveller:
Could you explain a bit further about binding the Enabled property to IsSavable. IsSavable doesn't show in my list.


Its not showing in Visual Studio because it is marked with an attribute in CSLA as not browsable. That is so that IsSaveable, IsDirty etc don't show up inconveniently as checbox columns in grids etc.

See this article from Rocky for the recommended way to handle those buttons using the binding source's CurrentItemChanged event.

http://www.lhotka.net/Article.aspx?area=4&id=5faaee8e-8496-4845-86f7-787c6b64096c

That works fine for me. Nearly all my forms have consistently named OK, Apply, Cancel and Delete buttons. I have a helper function that is called from CurrentItemChanged and takes the BO and the form. It looks for the existance of those buttons in the form's Controls collections and sets them appropriately from the BO properties. The function is actually in a base form class that I inherit most of my forms from.

Early on I used direct binding to those properties like you are trying now. I have a class in the inheritance between CSLA objects and my own (always a good idea) and I went against Rocky's plan and made those properties browsable in my inbetween class. That worked okay until I had a root BO on a form with a editable child collection in a grid on the same form. To make it work you need to catch the ListChanged event in the root BO and fire a PropertyChanged event I think it was. This is so that those buttons work correctly when you change a propery on a child object. That caused me a lot of problems with multiple events being fired back at the grid. Cancel especially did not go smoothly. Using the CurrentItemChanged event is very simple and works so much better. Once I did that and followed the other recommendations from Rocky about databinding, things worked beautifully and I've never looked back. Smile [:)] See the articles about doing EndEdit and CancelEdit on the bindingSource, not your BO, and doing these in the correct order if you have root and child. 

As an optimisation (probably not really worth the trouble but ...) my forms have a bool flag allows me to enable or disable the setting of button state on CurrentItemChanged. Some things like Cancel can cause a lot of events but you really only need the buttons set once when its done so I disable the updating, do the Cancel and then call my button update function once.

Cheers
Ross

ozitraveller replied on Thursday, July 12, 2007

Thanks Ross

Copyright (c) Marimer LLC