views:

70

answers:

4

I'm commonly working on GUIs where I want to directly prevent a user from doing things they should not be able to do by disabling controls on a form. For example maybe I don't want the "Process Widgets" button to be enabled unless the user currently has a "Widget Project" open in the application? Or the "Cancel Processing" button only becomes enabled when the widget processing is running.

Is there a commonly used design pattern to synchronize changes of state in the object model with the state of the GUI?

+1  A: 

Sounds like you are looking for the ability to subscribe to certain events. I would say use the observer pattern. The state pattern is a bit over kill for something in this situation [if it was greater than a binary condition then you could fit the state pattern to working for it]

monksy
A: 

I'm no expert, but lately I've been reading about the Model-View-ViewModel pattern for WPF, which is basically a MVC pattern taking advantage of WPF features. Since you're on winforms, you could try the Model-View-Presenter pattern. There's an article here about it.

If you can switch to WPF (though I have a feeling winforms has something similar), it sounds like you definitely want to use the Commands feature. It has some of the features you want built in. Basically any button or whatever subscribes to a command, and there's a single logic part that determines if the command is enabled or disabled. You'd just have to make that check your model's state.

Benny Jobigan
+1  A: 

MVC and Command patterns should work here. The basic idea is that you need to send a 'message' (which could be an object or string or anything really) to the GUI to notify it to change its state and how. You just have to be careful to take into account any delays that might occur from the GUI receiving and processing the message.

You can create a queue of events (associated with commands) and make sure that the first one in is the first one out (hence queue). Then have the GUI process the next event in the queue, this would ensure that the GUI is updated before you fire another event to do the thing you just tried to disable. Then you can report the error or ignore it or whatever. Either way, the user won't be able to do something once the command to disable that functionality was received. The disabling of the GUI button is just a visual effect and there should be prevention code for the commands in the background that really do the work for you.

Brian T Hannan
A: 

This is not applying to winforms, but Qt recently introduced a state-machine framework to ease changing the state of UI elements based on the internal state of the application. See the Qt documentation for more information.

This idea can probably be applied to a winforms based application as well. It might cost considerable initial effort though. I am not aware of any existing implementations.

Ton van den Heuvel