|
We know that many things in code are possible, but that doesn't mean you have to code something horrendous.
To me, having an option on a property page control the "spawning" of additional property pages (Tabs) is just rediculous (what makes it worse is that it creates an error when repeated or simply trying to use.)
Are there some good design resources or user interface style practices (on the Net or book form) that I can share with my clueless collegue?
Much thanks before I explode in anger.
JJM
|
|
|
|
|
john john mackey wrote: Are there some good design resources or user interface style practices (on the
Net or book form) that I can share with my clueless collegue?
Official Guidelines[^] from Microsoft.
Bastard Programmer from Hell
|
|
|
|
|
awk! I saw the Microsoft site, but aren't these the same people who created the horrible interfaces that are cited in the "How not to create an interface" links found on the Net?
Yes, the MS site had some good suggestions. Thank you.
JohnJohn
|
|
|
|
|
john john mackey wrote: Yes, the MS site had some good suggestions. Thank you.
My pleasure
..and yes, there are some good arguments in there.
Bastard Programmer from Hell
|
|
|
|
|
I need a bit of approach advice.
I have 2 forms that have the same custom section of form drawn in each. The controls are drawn according to some data in the database.
At the moment I thought about copying the Code from one form to the other but I am sure there is a better way!
Any pointer for me to read upon ?
Lobster Thermidor aux crevettes with a Mornay sauce, served in a Provençale manner with shallots and aubergines, garnished with truffle pate, brandy and a fried egg on top and Spam - Monty Python Spam Sketch
|
|
|
|
|
If the same piece of UI appears on more than 1 form, it would seem prudent to create that part of the UI as a UserControl and host it on both forms. The logic should be encapsulated neatly then.
|
|
|
|
|
potentially a blonde question here but
is it considered better to pass the database data too it rather than getting the user control to query the database?
Lobster Thermidor aux crevettes with a Mornay sauce, served in a Provençale manner with shallots and aubergines, garnished with truffle pate, brandy and a fried egg on top and Spam - Monty Python Spam Sketch
|
|
|
|
|
I would have a central repository for the database data. a cache if you like, and just query that from the user control - it's one location for the UC to talk to, and it's easy to implement using a static class.
|
|
|
|
|
As an alternative; create a form that contains the common controls, and inherit both other forms from there.
Making it a UserControl, as already suggested, would be a better idea though
Bastard Programmer from Hell
|
|
|
|
|
Personally, i would go for the inheritance method even thought user control is a great approach.
|
|
|
|
|
John T.Emmatty wrote:
Personally, i would go for the inheritance method
even thought user control is a great approach.
It's an option; but you can use multiple UserControls in different forms - and inherit only from one form at a time.
Bastard Programmer from Hell
|
|
|
|
|
Why not have a custom control that wil talk to database and render itself accordingly. this can be used on both the forms.
|
|
|
|
|
For simplicity and focus: the whole issue of "multiple undo'redo" is left "off-the-table" here at every level discussed. Also, for simplicity, the idea of a global "restore all settings to default values" is ignored here.
Suppose you have an application that has many (as in over one-hundred) user-configurable settings, and these are easily divided into several "functional areas of related settings."
Very logical to assume you have some overall selector UI/control to choose a focal "functional area:" and, when that area is selected, you present a UI with all the various controls necessary to set the options for that area.
Now let's say you endow each UI for each "functional area" with five "state-changing options" ('Undo' and 'Redo' can be handled by the usual keyboard shortcuts): possibly, three "buttons:" Save, Cancel, Reset
1. Undo / Redo : the usual: reverse/restore the last/previous change in the last control that had focus, and that you changed, in the current area.
2. Reset: which restores all local settings in the area to the state they were in when you first opened up this particular area to modify settings. Possibly confirm required by modal dialog.
3. Cancel: to my mind Cancel and Reset kind of have the same result, although Cancel usually implies a switch in focus to some other mode in the UI. Possibly confirm required by modal dialog.
4. Save: keep mind that "Save" here applies only to the specific area of functionality that is currently presented for settings modification.
The issue now arises, that if the user puts the focus back on the area selector UI, and chooses another area of settings to modify: should it be a requirement that they must choose to 'Save, or 'Cancel ... as the settings UI switches ?
Now, finally, to the more interesting point: the end-user has "moved through" some number of the functional areas, and altered settings, saved them, and now wishes to close the "settings ui."
At that point comes ... to my mind ... an interesting group of possibilities: as the settings UI is "closed:" in which case we'll assume there are two choices: Cancel, and Save.
1. Cancel: at that point what does the application "owe" the user:
a. summary information about which areas of settings have been changed and saved, or changed and not yet saved ? A "super-duper" warning dialog that all changes are going to be ignored ?
2. Save: at that point, if there no "modal exit" from each area of settings is required: and there could be area(s) in which settings have been changed, but not yet saved: should the app present some UI that allows the user to check that these areas of changed settings should be ignored or saved before the settings UI is closed ?
Discussion: obviously implementation of such configuration interfaces can be done with varying "philosophies:" you might think of a continuum from:
1. ultimate laissez-faire: you change a setting in any functional area and its changed for the app right then and there, no Save button required on any functional area UI. Switch to another area, close the settings UI: no worry, your settings are saved.
2. ultimate uber-control-freak ocd: every possible exit from any area of the total UI, from functional areas, to the whole shebang, when any change has been made in a settting: requires the end-user to confirm by modal dialog.
Appreciate your thoughts about what you view as your own "best practice" in this kind of scenario.
thanks, Bill
"It is the mark of an educated mind to be able to entertain a thought without accepting it." Aristotle
|
|
|
|
|
Hi Bill,
1.
over one hundred settings is quite a lot. I hope there is a lot of orthogonality in there, so the "mental model" complexity is limited.
2.
I advice to go for the simplest save/cancel/reset/redo/undo stuff that is sufficient for the job.
3.
when settings are grouped somehow, and their changes should be applied per group, rather than individually, I advice against tab pages (which one normally can switch away from at will, leaving multiple dirty pages, most of them out of sight).
4.
my preference goes like this:
- for each "functional unit", provide a separate modal dialog;
- give each dialog only two exit buttons: Save and Cancel; I tend to color them green and red respectively.
- give all controls their initial value; change their backcolor as soon as the user changes their value (so he can see what got saved changed before deciding on save/cancel);
- keep an accurate "modified" flag, and only enable the Save button if some change really has been applied;
- validate the inputs, don't allow the user to save invalid settings.
- optional: provide a way to reset a single control to its initial value;
- optional: provide a way to reset everything in the dialog to its initial value (not essential, user could cancel and open the dialog again).
5.
the above scheme may have two disadvantages:
4a. you can't modify settings of two units simultaneously (if they interact strongly, you might want to be able to do that);
4b. problems arise when functional units and their dialogs start to become hierarchical: when a parent dialog opens a child dialog, which gets closed by clicking Save, what should the parent's Cancel do? are the child's changed settings saved anyway (easy to implement), or is everything canceled? (more logical).
HTH
modified 2-Jan-12 13:19pm.
|
|
|
|
|
Thanks, Luc, for your detailed and thoughtful comments, and ideas, on the various issues and possible solution methods in this "problem space," in which, clearly, there's no "one-size-fits-all" implementation.
One point: it is very easy to restrain the end-user from switching tab-pages in a WinForms TabControl by simply defining a TabControl_Deselecting EventHandler, and setting the 'Cancel property of the TabControlCancelEventArgs argument to 'true.
It is interesting to me to study the massive preferences/configuration facilities in programs like UltraEdit, ReSharper, and Visual Studio.
And, I suppose if there's an "aboriginal" model for setting preferences/configurations across a range of functional areas ... it's the Windows Control Panel (?): of course that is such a diverse collection of all kinds of functionalities, there's hardly what you might have termed "orthogonality" in it !
I think the "point" the implementor chooses along this hypothetical continuum of preferences UI design between "laissez-faire" and "uber control-freak" ... for the degree of user confirmation of change ... has a lot to do with the nature of the application, and its broader context.
Nuclear power plant control comes to mind, at one of the end of the spectrum, and preferences for "Angry Birds" (?) at the other It's easy to imagine one scenario requiring writing logs for every single change of any application preference or setting, and another app that just needs a context menu with, maybe, one or two levels of whatever.
best, Bill
"It is the mark of an educated mind to be able to entertain a thought without accepting it." Aristotle
|
|
|
|
|
The Control Panels approach in Windows is highly orthogonal, as each panel controls a number of settings that is unrelated to the next group. And it follows my suggestions pretty well: one window per group, each window having an OK and a Cancel button, etc. The major deviation is they are separate processes and hence can show their dialog simultaneously.
|
|
|
|
|
Ah, Luc, I see you and I are using the term "orthogonal" in very different ways: to me "orthogonal" means some encapsulating context in which some group of objects, or functionality, are:
1. integrally related
2. enveloped/contained/framed by a consistent "user-interface" for each integrally related "component."
Would you say that a "garbage can" is orthogonal because you can stuff anything in it that will fit it in it ?
Yes, that's an extreme "reductio ad absurdum:" but, to me, the Windows Control Panel, is just a container for a whole bunch of stuff, almost every one of which has a totally different UI, some of the Control Panel Items when opened then lead to even further radically different UI's.
If there's one thing that has characterized Windows from early version right up to 7, it's lack of orthogonality: inconsistency in which some parts of the UI save their configurations, and others don't.
For example: the order in which Date/Size/FileType/FileName are presented in Explorer Windows which may change based on no principle I can discover with the rational mind: or the sudden decision if you open a folder with .MP3 files, or photo files, to present all kinds of possibly not desired Explorer view columns.
Bizarre UI inconsistencies like having a slider control in the View menu to switch between Icon/Detail views.
Multiple UI pathways to configure different areas like Display characteristics.
It's been much too long since I had a Mac to compare with, on these criteria, however.
But, what can you expect from the evolution of dinosaurs ?
Looking back, I wish Apple had acquired Be, not NeXT, but then there would have been no Steve Jobs to restore the company by making it into a mass-media-player and mobile-phone colossus.
best, Bill
"It is the mark of an educated mind to be able to entertain a thought without accepting it." Aristotle
|
|
|
|
|
BillWoodruff wrote: 1. Undo / Redo : the usual
My usual looks like a Memento.
BillWoodruff wrote: 2. Reset: which restores all local settings in the area to the state they were in when you first opened up this particular area to modify settings. Possibly confirm required by modal dialog.
BillWoodruff wrote: 3. Cancel: to my mind Cancel and Reset kind of have the same result, although Cancel usually implies a switch in focus to some other mode in the UI. Possibly confirm required by modal dialog.
Sounds good, even though you should not rely on your own preferences, but on the expectations of your users.
BillWoodruff wrote:
4. Save: keep mind that "Save" here applies only to the specific area of functionality that is currently presented for settings modification.
Your "save" is what other applications call "OK" as confirmation, assuming that you're showing your settings in a modal dialog.
BillWoodruff wrote: The issue now arises, that if the user puts the focus back on the area selector UI, and chooses another area of settings to modify: should it be a requirement that they must choose to 'Save, or 'Cancel ... as the settings UI switches ?
No, only when the settings are dirty.
BillWoodruff wrote: Now, finally, to the more interesting point: the end-user has "moved through" some number of the functional areas, and altered settings, saved them, and now wishes to close the "settings ui."
..he presses "Ok", "Apply" or "Cancel"? I agree that "Reset" might be valuable. And yes, if you're not using a modal UI, than it might sound reasonable to name it "Save".
BillWoodruff wrote: 1. Cancel: at that point what does the application "owe" the user:
a. summary information about which areas of settings have been changed and saved, or changed and not yet saved ? A "super-duper" warning dialog that all changes are going to be ignored ?
When the user exits the form, while there's still dirty. Pop up a MessageBox telling the user that there's unsaved sh*t, asking whether he want's to save them (Yes, No, Cancel). Yes defaults, and you can keep a history of the previous "setting" in your table. That way you'll always be "safe" when the user blindly confirms the dialog
BillWoodruff wrote: 2. Save: at that point, if there no "modal exit" from each area of settings is required: and there could be area(s) in which settings have been changed, but not yet saved: should the app present some UI that allows the user to check that these areas of changed settings should be ignored or saved before the settings UI is closed ?
None of the apps that I know thoes that, not counting installation-packages. I'd go for a "Save all" or "Loose all" option, unless there's some good reason to show a summary.
BillWoodruff wrote: 1. ultimate laissez-faire: you change a setting in any functional area and its changed for the app right then and there, no Save button required on any functional area UI. Switch to another area, close the settings UI: no worry, your settings are saved.
That's a lazy-developers' tactic, that could lead to users resetting a lot of changes, simply because they need to undo the last three changes. It might also lead to accidental changes, where people press a button repeatedly to wake the computer and kill the screensaver.
BillWoodruff wrote: 2. ultimate uber-control-freak ocd: every possible exit from any area of the total UI, from functional areas, to the whole shebang, when any change has been made in a settting: requires the end-user to confirm by modal dialog.
..and piss of your users. Simply, would you like to confirm every step? Would you actually read any dialogs of that application at all?
BillWoodruff wrote: Appreciate your thoughts about what you view as your own "best practice" in this kind of scenario.
Done, hope that it didn't offend to much. Best wishes for coming year
Bastard Programmer from Hell
|
|
|
|
|
Hi Eddy, I was delighted with the range of your comments and feedback, in no way "offended" !
My preference ... which I did not specify in my original post ... is to have a 'Save button per functional-area UI which is disabled on entry, and enabled any time a change has been made.
I use a TabControl from a third-party vendor (Lidor) that would also easily let me change the colors of tabs to indicate preferences on that Tab changed, but not yet saved.
The issue Luc raises of coloring changed values to reflect they are changed I also find interesting, and I am going to explore the "cost" of a custom pop-up that might let you "revert" on a per setting basis.
If you'll see my response to Luc's ideas, above, you can also get some idea of how I think a developer might in one case go for a very strict "confirm everything damn thing: or stay 'locked-into' where you are in the UI area" vs. the "laissez-faire" approach.
You wrote: "even though you should not rely on your own preferences, but on the expectations of your users." To which: all I can say is: "wisdom !"
thanks, Bill
"It is the mark of an educated mind to be able to entertain a thought without accepting it." Aristotle
|
|
|
|
|
BillWoodruff wrote: in no way "offended"
Cool, my pleasure
BillWoodruff wrote: The issue Luc raises of coloring changed values to reflect they are changed I also find interesting
True, gives a visual indication of what's dirty.
BillWoodruff wrote: and I am going to explore the "cost" of a custom pop-up that might let you "revert" on a per setting basis.
Didn't realize it, but VS offers the same in the PropertyGrid. And yes, I've used that function.
Thanks for sharing
Bastard Programmer from Hell
|
|
|
|
|
BillWoodruff wrote: (as in over one-hundred) user-configurable settings
Depends on specifics but that isn't very many.
It can be handled as a single block even though displayed as a different groupings.
The settings, for editing, are all copied into memory.
If the user hits 'Ok' at any time then the current set is written. If the user never hits 'Ok' then nothing is updated.
There is no confirmation on exit. After all the user either explicitly wanted to change something so they are going to hit 'Ok' or they accidentally changed something and a confirmation is going to confuse them.
Reset of course means that there is a copy somewhere where the delivered values are kept and which is never overwritten.
|
|
|
|
|
Hi, thanks for your response !
I admit to a bias about using "Okay:" to me "Okay" is appropriate for confirming a direct question that is "binary" in nature. I like "Save" better: personal taste.
I can't imagine a case where preference "settings" are not already in memory in order to be used in the Application, "embodied" in some kind of data-structures: with that in mind: "revert" is easy.
I also prefer to see a "Save" button disabled as long as no changes have been made, and enabled when they have: similarly, I like the idea of a "Revert" button also disabled until changes have been made (although that could also be handled, as I noted in my first post, by Control-Z/Y keyboard functionality).
I do think use of separate 'Revert' and "Cancel" controls are sometimes appropriate. The idea of "revert" on a per setting basis, perhaps using color as a flag to indicate a changed value, as raised by Luc, I find very interesting.
You wrote: "There is no confirmation on exit. After all the user either explicitly wanted to change something so they are going to hit 'Ok' or they accidentally changed something and a confirmation is going to confuse them."
On this issue I respectfully disagree: if I have "waded into" a complex configuration UI, and made many changes: or changed something accidentally: I definitely want to know on exit if changes have been made ... most strongly when I am under the impression (in error) that I did not change any preferences.
thanks, Bill
"It is the mark of an educated mind to be able to entertain a thought without accepting it." Aristotle
|
|
|
|
|
BillWoodruff wrote: I also prefer to see a "Save" button disabled as long as no changes have been made, and enabled when they have: similarly, I like the idea of a "Revert" button also disabled until changes have been made
That is adding complications with no benefit.
Scenario
1. Monday I changed config value X. And save/ok.
2. Tuesday I changed config value Y. And save/ok
3. Wednesday I can't figure out why it isn't working the way I want but I guess 1/2 had something to do with it. So I want to revert to the original default settings.
To handle the above case then you must do a comparison with the original values every time you load. That of course complicates things.
But there are only two cases.
A. The user has in fact made a change in the past. So Revert is always on and will always be on.
B. The user has never made a change in the past.
In the first case it matters if the user hits Revert. In the second it doesn't matter at all.
So you are doing work that doesn't mean anything. So pointless. Revert should always be enabled and should just always copy the original values into the use location.
And it could be the case that a config value must always be changed, such as if a database is required. In that case revert would always be enabled for everyone.
BillWoodruff wrote: I do think use of separate 'Revert' and "Cancel" controls are sometimes appropriate. The idea of "revert" on a per setting basis, perhaps using color as a flag to indicate a changed value, as raised by Luc, I find very interesting.
Depends on you and your app of course but exactly what sort of config values are these?
For example if I have an inventory app and I set the database host name, I don't need to do it again.
If I have an editor and I want to change the font color then it is pretty obvious what it is, and I certainly don't need a reminder that I changed it.
BillWoodruff wrote: On this issue I respectfully disagree: if I have "waded into" a complex configuration UI, and made many changes: or changed something accidentally: I definitely want to know on exit if changes have been made ... most strongly when I am under the impression (in error) that I did not change any preferences.
You must be dealing with different sorts of users then.
If I am writing an editor then I expect that the users know that they are actually using an editor and that they expect certain functionality from the editor. If they go poking around in the config font colors for the editor and change it I don't expect it to be confusing to them when the the font color does change.
And if there are config values that users shouldn't be messing with in most cases then I am not going to make it easier for them to do so. So no UI in the first place.
But for comparison I looked at some apps.
TextPad
- Has a Ok button, always enabled, not sure of the point but I presume it does 'Apply'
- Has a Apply button. Only enabled if I change something.
- Has a Cancel. Always enabled.
- No revert at all.
VS 2010
- Has Ok and Cancel. Both enabled. No other buttons.
Cisco VPN
- Has Ok and Cancel. Both enabled. No other buttons.
Firefox
- Has Ok and Cancel (and Help). All enabled.
WinAmp
- Has Close (only the one button.) Always enabled.
Given the above just having simple revert puts you way ahead of the curve. Of course that could be problematic I suppose. I don't want the inventory app to ever return to the factory database host, since that probably is always wrong.
|
|
|
|
|
Hi,
I have a "philosophy" of interface design, which I am continually modifying: it's been an interest going back to SmallTalk on the Xerox Alto.
I am highly critical of many design aspects of Windows up to and including version 7.
Equally critical of the "bright chiclet auto-expanding" graphic chotchkas of the current Mac UI desktop (but, that's a "religion," after all).
In your response above I find a dis-jointed potpourri of the ideas of "Save," "Apply," "revert (undo)," "multiple revert (undo)," and "restore application setting defaults for the whole banana." Not to mention the ideas of saving complete, or partial, "snapshots" of part, or the entire, state, of an application.
Each of those implementation details, imho, will be more or less appropriate depending on application design, purpose, security concerns, etc., and level of sophistication of end-users. The "security fence" I'd want a System Admin to be in, where changing a setting that might affect a hundred computers on a network needs a rigorous confirmation process, is irrelevant to TextPad or Angry Birds
In some cases you want highly specific undo/redo facilities with a perhaps user-configurable history mechanism (as PhotoShop does for undoing graphic operations per document, for example, where the end user can specify the number of history states to be maintained) for certain types of UI actions, but have no need for such mechanisms with other properties of the application.
And the kind of configuration/settings I am speaking about are not trivial, self-evident, modifications like the background color of selected text in an editor application, like UltraEdit.
The trivial case in which "Okay" is "okay:" is one in which there is a simple binary choice affecting one user setting or preference, or where the visual cues in the settings area show you exactly what you are going to get when you do click "Okay: like in UltraEdit's compex configuration panel for setting the foreground and background colors of no less than ten text parameters. However UltraEdit also has a 'Save' button on that modal dialog that will auto-increment, and you can then re-open any previously saved configuration, which is quite handy ... no need to type an "original name" every time for each new configuration saved.
As I've carefully explained in my original post, and in my comments to other posts on this thread, I think there is a continuum of confirmation-requirement by the end-user that varies with the context in which the application is used.
The program examples you mention, including Visual Studio, have some absolutely grotesquely stupid design decisions. UltraEdit, while my tool of choice, for all text editing, in use every day, scatters its complex configuration UI's across multiple top-level menu items. To me "WinAmp" is the design equivalent of a Pachinko machine
best, Bill
"It is the mark of an educated mind to be able to entertain a thought without accepting it." Aristotle
|
|
|
|
|
Hi there,
Anyone knows the best way to use barcode in an inventory and POS system? I mean should I simply just read the barcode and use the Part number as an ID (Primary key) for the item, or is there a better way?
Thanks.
|
|
|
|
|