Recently, I've been doing alot of reading on UI design. One of the unfortunate problems with typical Winforms applications is the lack of style or regard for attractiveness and usability of the application. Looks aren't everything, but they'll go a long way, especially with a novice end user. As developers (especially backend developers), we typically lose sight of the importance of an attractive application, and on't spend much time tweaking the UI to suit a consumer. To beautify out applications, and make them feel friendly and easy on the eyes to our end users, we must take into account some very basic concepts:
- Don't Hide Features - The most important options must be available up front, and should not be buried or poorly labeled.
- Follow Design Guidelines - It seems most developers (especially web developers) seem to have a lack of understanding of basic design guidelines when it comes to building UI's. One of the most irritating things to a user is when the UI isn't what they expect. Try following the Official Windows UI Design Guidelines (link) to ensure that you provide a consistent look and feel to the rest of Windows applications.
- Grids and Fields Are Evil - Well, not evil, but think how painful it is for a user to see a huge grid of textboxes, or an array of fields that you plainly laid out with no direction other than their labels. When designing forms, try to keep the number of fields to a minimum. Break them into steps, or break apart the fields with headers.
- A Picture's Worth 1000 Words - When designing a UI, don't forget the icons! Icons are very important visuals to a user and they make your application look more professional, feel friendlier, and keep the user from reading too much. Try http://www.iconexperience.com for a great suite of XP looking icons.
- Design For Illiterate Users - As mentioned in the previous point, reading too much is bad. In fact, users typically don't read -- so if you can, make your application self-explainatory and use icons and images to give the user feedback.
- Good Winforms Design Often Requires Custom Rendering - If you are looking to build a unique and engaging experience, the out-of-the-box Winforms controls generally don't cut it. You may want to look into some third party controls (http://www.divelements.co.uk will handle alot of your needs), and OwnerDraw or GDI+ rendering of controls may often be necissary to acheive the results you're looking for. This is Winforms, not HTML so go wild with custom rendering if you want!
- Office Ain't All that Bad - Users like MS Office. In fact, users often expect your application to work like MS Office. For that reason, when in doubt, make sure you're mimicing the way that Office works!
This kind of stuff really should be taught in school. Good UI's can really make or break an application.
For further reading, I strongly suggest the book User Interface Design For Programmers by Joel Spolsky. Possibly the best (only?) UI book ever written for developers.
See the Visual Studio 2005 (.NET 2.0) attached code here
A common problem when working with smart clients or any client that you deploy to an end users desktop is the ability to diagnose problems that arise in the users application. Because the application is not hosted on a server, the various problems that exist for a given user can vary. Worse, users typically cannot remember what actions they performed to cause the error.
A solution:
To aid us, we must create some level of communication back to the software vendor, allowing the vendor some insight into various attributes of the client application. The following attributes are amongst the most important things we'd like to know about a client-side application.
- What modules and assemblies are loaded?
- What is the configuration of the system its running on?
- What does the application look like and what state is it in?
- What did the user do to cause the application to fail?
We can solve this problem by creating a framework that uses a little reflection to allow us to "peek" into the forms and properties of the currently running application.
To get modules, system information and state, we can look at the AppDomain.CurrentDomain.GetAssemblies() method to get the loaded assemblies.
To get the system information, we can easily get the properties of the SystemInformation class.
To get the state of the app (how it looks), it is a good idea to get the properties of the form. To achieve this, we can use reflection to look at every property of every control and write out the details of all the controls (recursively) on the form. This will give us a good idea of what we're looking at.
Lastly, if we have built our application with a decent amount of instrumentation (such as a trace call at the beginning (and maybe end) of all our big operations or form events, we can get a good picture of what the user has done by caching those Trace.Write calls so we can write them out in the event of failure. Better still, we can wrap Trace.Write so that every call provides us additional information, such as which thread we're calling from.
To demonstrate this, you can download the code sample I've provided with this blog entry. Run the Winforms application and play with the buttons and textboxes. Then click the "Help -> Send Diagnostics" menu item to write "test.txt" to your working directory. This will be a dump of all the data mentioned above. Ideally, you would send this through email or a remoting call to your support group.
In addition, catching the Application.ThreadException (see the Program class in the winforms test) will allow you to log this data prior to a crash, allowing you to figure out what went wrong without user intervention.
Please note: To use this code in your own example, you must add the trace listener as seen in the app.config of the winforms project.
Code Sample: .NET 2.0 Code Sample is available here