Creating User Interfaces in C# using WinForms
Lesson 1
User Interface Design Principles
- Ease of use = paramount importance
- Design of UI primary consideration = target audience
Forms, Controls, Menus
-
Form
- Primary element of UI
- Contain related info / options - provide user with info required to proceed
- = class
- can create multiple instances of form
- can inherit from form
-
Control
- Make information / options accessible
- Some display info (e.g. labels, picture boxes)
- Some display and accept info (e.g. text box, list box, combo box)
- Others (e.g. button ) allow course of action to be selected
-
Menu and toolbars
- Expose available commands in structured fashion
- Menus provide access to high level commands common to all forms in application (e.g. save, exit)
- Items can be enabled / disabled to control options available at different times
Composition
-
Simplicity
- V. important
- Only expose functionality needed at that stage of application
- Use tab orders to facilitate rapid navigation
- Don't reproduce real-world objects (e.g. paper forms) - utilise capabilities added by computer
- Use default values (based around target audience)
- Utilise user feedback when designing UI
-
Positioning
-
Reflect importance and frequency of use
-
Most UIs read left-to-right, top-to-bottom
- Important / frequently used at top of form
- Controls used after from completed (e.g. submit button) placed according to logical flow at bottom of form
-
Group related information
-
-
Consistency
- Key = design
- Consistently use colours, fonts and control types
- Only use what is needed - don't show-off
-
Aesthetics
-
Avoid busy forms
-
Colour
-
Use muted, agreeable colours
-
Design around target audience
- Corporate colours
- Cultural significance
-
Avoid hard / unreadable combinations
-
High contrast in important elements of application
-
Don't rely on alone to convey information
-
-
Fonts
- Consistent throughout application
- Avoid embellishments - use simple ones (e.g. Times New Roman)
-
Images and Icons
- Add interest
- Avoid distraction with busy images
- Be aware of cultural significance (e.g. road signs for STOP vary)
- Keep icons to shapes that can render within 16 x 16 grid
-
-
Shapes and Transparency
-
Do not overuse unconventional shapes
- Doughnut shaped text box may be unique but is unusable
-
Transparency can be used to manipulate controls while monitoring background activities
-
Lesson 2
Using Forms
- Can create app without forms, e.g. service or console application, but rare
- Apps with frequent user interaction have at least 1 form
- Complex apps may require several forms
Adding Forms to Project
- Create new Windows Forms project receive initial form named Form1
- Form1 = class representing code behind an instance of Form1
- Add additional forms
-
Through IDE
- On Project menu select Add Windows Form
- On Add New Item dialog click Windows Form and Open
-
Programmatically
- Declare variable representing type of form
- Create instance of form
-
// Assumes form called DialogForm
// already designed by you
DialogForm myform
Myform = new dialogForm()
Visual Inheritance
-
Used to create several closely related forms
-
Allows a form to incorporate all members, controls, menus and code of existing form
-
Create base form with common UI elements
-
Use inherited forms to provide specific behaviours
-
Add visual inheritance through IDE
- On Project menu select Add Inherited Form
- From Add New Item dialog choose Local Project Items in left pane. In right pane select Inherited Form. Provide a name and click Open.
- Inheritance Picker shows Forms in project. Choose one to inherit from and click OK
or
- To inherit from form outside project click Browse and navigate to appropriate application. Click Open and choose desired Form.
- Add visual inheritance through code
// Derive from MainForm residing within project
public class myForm : MainForm
{
}
Set Startup Form
- If app contains multiple forms must designate one for startup and it must have a Main method
static void Main()
{
}
- Choose any form (implementing Main) in Startup Object of project properties window
Form Start Location
- Form StartPosition property select
- Manual - open at Location property
- CenterScreen - open centred in screen
- WindowsDefaultLocation - open at default location
- WindowsDefaultBounds - open at default location and size
- CenterParent - open centred within parent
Changing Appearance
- Some properties controlling appearance are structures. Expand by clicking '+' in properties window
- Can change properties via code
// Change form colour within its implementation
this.BackColor = System.Drawing.Color.Red;
BackColor, ForeColor, Text Properties
- Text = form caption
- BackColor and ForeColor control forms colour
- Controls inherit ForeColor from parent form
- Many have also have BackColor from parent, others (e.g. text) are independent
- Choose colours carefully - aim for high contrast
Font, Cursor, BackGroundImage
- Once Font changed on form it is applied to all controls within form (for consistency)
- Cursor controls icon displayed while mouse over form
- BackGroundImage places specified image as form backdrop. Overrides Backcolor setting
Opacity
- Opacity controls form transparency, range 0 to 1
- 0 = opaque, 1 = transparent
- Control inherits form opacity
- In property window Opacity represented as percentage
Form Methods
- Methods perform actions
- Every form inherits functionality from System.Windows.Forms.Form including
- Form.Show - causes form class to load, display on screen (Visible property set to true) and receive input focus. If form already in memory effect = setting Visible to true
- Form.ShowDialog - same as Form.Show except form displayed as modal dialog (no other app forms can be interacted with until this form dismissed)
- Form.Activate - shifts input focus to form currently visible. If form not visible, method has no effect
- Form.Hide - remove form from view, but maintain in memory. Sets Visible property to false
- Form.Close - closes from and removes from memory. If called on application startup form then application closed
Form Events
-
Interesting occurrence occurs, raises event enabling other portions of app to handle event
-
Each control and form can raise events, e.g. FormHide method raised Deactivate event and VisibleChanged event
-
Developers create event handler - a method executing in response to event
-
Create via IDE or programmatically (latter more complicated)
- Select form or control to host event handler
- From properties window click Events button (lightning bolt)
- Select desired event from list
-
Some events raised during forms lifetime
- Load - fired when instance of form first loaded via Form.Show or Form.ShowDialog. Only raised once per form instance. Use to initialise form + prepare for use
- Activate - raised when form receives input focus (Form.Show, Form.ShowDialog, Form.Activate). Use to set focus to particular control. Does not fire if click on another app and then return
- Deactivate - raised when form looses input focus (Form.Hide, Form.Close). Use to validate user input. Does not fir if click on another app
- VisibleChanged - raised when visible property of form changes (Form.Show, Form.ShowDialog, Form.Hide, Form.Close)
- Closing - form in process of closing but not yet closed (Form.Close). Use to verify all tasks require by form have completed - can abort close if required
- Closed - raised after form closed (Form.Close) and handlers for Closing event completed. Use to execute clean-up code
Lesson 3
Using Controls and Components
-
Control
- graphical tool to create / enhance app functionality
- hosted by form
- added from toolbox
- some, e.g. button, textbox receive user input and perform simple tasks
- customise functionality via event handlers
-
Component
- similar to control
- do not have visual representation, e.g. timer
-
Together implement most app functionality
Working with Controls and Components
-
Add to form using designer which displays form in graphical state - similar to how looks at run-time
-
Designer adds code for control to app
-
Position and size via mouse
-
Properties window displays / permits modification of properties for selected control (or common properties of multiply selected controls)
-
Can achieve same through code but designer + properties window = easy!
-
Components no visual representation - placed into component tray, not form. Use properties window to change its properties
-
Add to Toolbox
- Select desired Toolbox tab
- Right click and select Customize
- If already registered select from appropriate list (.NET or COM)
- Otherwise browse to location, select and click OK.
-
Add event Handler
- Every control has default event, e.g. Button = click. To add handler double click control in designer
- For other events
- select control
- Click events button in properties window
- Find required event in list and select it
Control Tab Order
- Tab Order dictates sequence controls selected when tab key pressed
- Specified by controls TabIndex property - lower values receive input first. If two controls have same value focus goes to control closes to font of form (set by Bring To Front / Send To Back menu items)
- IDE has tool for setting Tab Order. From View choose Tab Order and click controls in desired order
Controls Can Contain Other Controls
-
Container controls allow others controls to be placed within them
-
Use to logically organise groups of controls - group set of related radio buttons within GroupBox
-
Logical groupings can be manipulated programmatically
-
Create sense of flow within UI
-
GroupBox and Panel
- Both provide logical and physical grouping
- Changes in their properties, e.g. Enabled, affect all contained controls
- Move + position all contained controls as group
- Groupbox provides caption to label contained controls
- Panel provides no label but is scrollable
-
TabControl
- TabControl hosts number of TabPages
- TabPages host controls
- Group controls onto a set of tabs
- Example = app property pages
- TabPages similar to Panel controls - scrollable subdivision of form
-
Controls collection
- exposed by all control containers
- Count property = number of controls.
- Item property = returns specific control
- Add and Remove methods support dynamic maintenance of controls within container
Control aControl;
aControl = myForm.Controls[3];
myForm.RemoveAt(2);
Docking and Anchoring Controls
-
Anchor
- Define constant distance between control and 1+ edges of form
- Fixed position in form by anchoring top and left
- Resize by anchoring to opposite edges
- Float freely by removing anchor
- Set via properties window. Choose Anchor property and choose edges to anchor control to
-
Dock
- Attach control to edge of form / completely fill form
- Docked control resizes with form
- Example = menu bar at top of form
- Set via properties window. Click on part of interface corresponding to edge of form to dock to. Clicking in centre causes control to fill form
- Anchor automatically set to top-left
Extender Providers
- Specialised components that provide additional properties to other controls
- E.g. ToolTip provider. Place instance on form and every control has new property - ToolTip - that is displayed when mouse hovers over control
- Others include HelpProvider and ErrorProvider
- Via Properties Window set new property for each control in turn
- Programmatically set values via the Extender Provider
// Retrieve ToolTip for button1
String myToolTip;
myToolTip = toolTip1.GetToolTip(button1);
// Set tooltip for button1
toolTip1.SetToolTip(button1, "Click this button for help");
Lesson 4
Using Menus
- Access top-level commands and functions in familiar, easy to understand interface
- Expose app functionality logically and consistently
- Group items according to functionality
Creating Menus at Design Time
-
Created via MainMenu component which manages MenuItem controls
-
Add MainMenu component to form
- Component appears in component tray
- Box with text "Type Here" appears in menu bar of form. Create new items by typing where indicated. Additional boxes created below and to right (below = menu items, right = new / sub menus)
- Each menu item represented by MenuItem object. Its properties can be adjusted in Properties window
-
Menu separators (horizontal bar) added as hyphen in text box
Access and Shortcut Keys
-
Menu access via keyboard
-
Access Keys
- Open menu via
Alt-<key>
combination, e.g. Alt-F for file - Select menu item in same way
- Can have same access keys for different menu items - provided they are in different menu groups. If in same group use access key to toggle between them, cannot select with Enter key
- Identified by underline character in menu item
- To assign type & in front of desired letter for access key in menu item
- Open menu via
-
Shortcut keys
- Instant access to menu items - shortcut for frequently used items
- Single key, e.g. Delete, F1, etc. or combinations -Ctrl+A, Ctrl+Shift+A, etc.
- Key combination written to right in menu (provided ShowShortcut property of menu is true)
- To assign
- Select menu item
- Select its shortcut property
- Choose key combination
Menu Item Events
- Create in same way as other controls
- Click - executed when menu clicked
- Select - menu highlighted, e.g. provide detailed help
- Popup - prior to menu items being displayed, e.g. enable / disable menu items
Context Menus
- Appear when item right-clicked
- Similar to main menus, access keys not supported
- Create with ContextMenu component (edit same way as MainMenu component)
- Can associate single ContextMenu with several controls - only cone menu per control
Enable / Disable Menu Commands
- Every menu has Enabled property.
- When false menu disabled (including action and shortcut keys) and greyed out
Check Marks On Menu
- Checked property displays check mark next to menu item
Radio Buttons On Menu
- Set RadioCheck property of menu item to true. Menu item will display radio button instead of check mark when Checked set to true
- Radio buttons used to indicate exclusive options - e.g. background colour. Must write own code to handle exclusivity
Menu Item Visibility
- Set Visible property to false
- Removes item (and any submenus) from menu - becomes inaccessible
Cloning Menus
- Can copy menus at runtime, e.g. clone edit menu form MainMenu to serve as ContextMenu
- Create new menu via CloneMenu method
- Cloned menu all original menu items, properties and event handlers
// Declare + instantiate context menu
ContextMenu myContextMenu = new ContextMenu();
// Clone fileMenuItem
myContextMenu.MenuItems.Add(fileMenuItem.CloneMenu());
//Attach context menu to myButton
myButton.ContextMenu = myContextMenu;
Merge Menus
- Display multiple menus (main or context) as single item
- Call MergeMenu method
mainMenu1.MergeMenu(contextMenu1);
Add Menu Items
- e.g. display path names of most recently opened files
- No event handlers associated with them, can add Click handler via constructor of new menu item
// Define event handler
Public void ClickHandler (object sender, System.EventArgs e)
{
...
}
MenuItem myItem;
myItem = new MenuItem ("Item 1", new EventHandler(myClick));
MainMenu1.MenuItems.Add(myItem);
Lesson 5
Validating User Input
- Validate UI -> reduced chance of input error
- 2 types
- field-level - control over UI as it occurs
- form-level - validate data after all fields completed
Field-level Validation
-
Use properties and events
-
Common control for UI = TextBox. Some properties include:
- MaxLength - limits number of characters entered
- PasswordChar - display text entered as '*' or other desired character
- ReadOnly - prevent entry of data in TextBox
- MultiLine - allow entry of multiple lines. Individual lines stored in array of strings (TextBox.Lines)
-
Keyboard events permit immediate UI validation
- KeyDown and KeyUp - raised when key pressed and released. Commonly used to determine if Alt, Ctrl or Shift pressed (via KeyEventsArg param)
- KeyPress - raised when user presses key that has an ASCII value (a - z, 0 - 9, special characters such as Enter). Ctrl, Alt and Function keys do not raise KeyPress. Intercept and evaluate keystrokes, e.g. ensure key pressed is numeric
- Validating Characters via static char methods such as Char.IsDigit, Char.IsLetter, Char.IsLower, etc. Return true if match
-
Focus = ability for object to receive UI
- Every control implement Focus method - sets focus to control that called it
- If succeeds method returns true
- Determine if control can receive focus by checking CanFocus property
- Following Focus events raised:
- Enter - focus arrives at control
- GotFocus - control obtains focus
- Leave - focus leaves control
- Validating - raised before control looses focus, only if CausesValidation property set (default). Validating event includes CancelEventArgs class - its cancel property when set to true causes focus to return to control
- Validated - raised after control validated. Perform actions based on validated input
- LostFocus - control looses focus
Form-level Validation
- Central procedure implements form-level validation, called when user proceeds to next step
- Keyboard handler
- more sophisticated form-level validation, e.g. only enable command buttons after input present in all fields
- events passed to form if no visible, enabled controls. Can force form to receive them first by setting KeyPreview property to true
User Feedback
-
User should be informed when invalid data entered
- Sound
- Change control colour
- Message boxes (modal dialog box)
-
Error provider
- Set error message for each control (either programmatically or at design time)
- When message set, icon indicating error appears next go to control and message displayed as tool tip
- Other properties effect behaviour, e.g. BlinkStyle and BlinkRate
- Call SetError method to cause error condition
myErrorProvider.SetError( nameTextBox, "Name cannot be blank");