Fruit basket program with Windows Presentation Foundation

  • From: Jamal Mazrui <empower@xxxxxxxxx>
  • To: programmingblind <programmingblind@xxxxxxxxxxxxx>
  • Date: Tue, 08 Jun 2010 22:32:56 -0400

From the archive
http://EmpowermentZone.com/wpf_fruit.zip

This contains essentially the same fruit basket program written with both the C# 4.0 and Visual Basic 10.0 command-line compilers that are distributed with the .NET Framework 4.0. Recent language features including type inference, property initializers, and lambda functions are used. Source code is in the files wpf_fruit.cs and wpf_fruit.vb -- the contents of which are also pasted below. Batch files to build the executables are compileCS.bat and compileVB.bat. Help on compiler options is also included in the files csc_help.txt and vbc_help.txt.

Windows Presentation Foundation (WPF) is used as the GUI library. Since its classes have some of the same names as those of the Windows Forms library (WinForms), the appropriate assemblies need to be referenced as parameters to the compiler. The included response files, csc.rsp and vbc.rsp, provide these references (the only difference between them is that the C# one uses a /lib parameter whereas the VB one uses a /libpath parameter to specify the directory containing WPF assemblies).

WinForms is generally a set of wrappers for native Win32 controls, which integrate Microsoft Active Accessibility (MSAA) as an accessibility API. WPF is a new GUI library, written from the ground up to support fancier visual effects, including animation. Rather than MSAA, the accessibility API is User Interface Automation (UIA).

Current screen readers vary considerably in their support for UIA, as illustrated by this fruit basket program. Window-Eyes 7.2 provides almost no meaningful access. JAWS 10.0 provides partial access in voicing some controls but not others. JAWS 11.0 and NVDA provide complete access.

Some differences between WPF and WinForms include the following:

* An underscore character (_) rather than ampersand character (&) is used to indicate the access key of a control (where Alt+Letter activates it). For the access key of a label to work, its Target property also needs to be set, e.g., to the TextBox that should receive focus when the key is pressed.

* The StackPanel and Grid layout containers of WPF correspond to the FlowLayoutPanel and TableLayoutPanel containers of WinForms. The source code illustrates layout with alternate containers, as well as alternate methods for actavating the dialog.

* The layout of the GUI may be expressed either in code, as done in this program, or in a separate text file written in the Extensible Application Markup Language (XAML). A fruit basket program developed with Visual Studio and XAML has been contributed by Jacob Kruger in the archive at
http://fruitbasket.quantummyst.com/downloads/fruitbasket-wpf.zip

Jamal


/*
content of wpf_fruit.cs
Fruit Basket program in C# 4.0 with Windows Presentation Foundation
Public domain by Jamal Mazrui
June 8, 2010
*/

// Import namespaces
using System;
using System.Windows;
using System.Windows.Controls;

// Define class
class FruitBasket: Application {

// Define entry point of program
[STAThread]
static void Main() {
// Create controls;
var txtFruit = new TextBox();
var lblFruit = new Label {Content = "_Fruit:", Target = txtFruit};
var btnAdd = new Button {Content = "_Add", IsDefault = true};
var lstBasket = new ListBox();
    var lblBasket = new Label {Content = "_Basket:", Target = lstBasket};
var btnDelete = new Button {Content = "_Delete"};

// Define Add event handler;
btnAdd.Click += (o, e) => {
var sFruit = txtFruit.Text.Trim();
if (sFruit == "") MessageBox.Show("No fruit to add!", "Alert");
else {
lstBasket.Items.Add(sFruit);
txtFruit.Clear();
lstBasket.SelectedIndex = lstBasket.Items.Count - 1;
}
};

// Define Delete event handler;
btnDelete.Click += (o,e) => {
var iFruit = lstBasket.SelectedIndex;
if (iFruit == -1) MessageBox.Show("No fruit to delete!", "Alert");
else {
lstBasket.Items.RemoveAt(iFruit);
if (iFruit == lstBasket.Items.Count) iFruit--;
lstBasket.SelectedIndex = iFruit;
}
};

// Complete layout
Window dlg;
var bUseGrid = true;
// bUseGrid = false;
if (bUseGrid) {
var grid = new Grid();
grid.ColumnDefinitions.Clear();
for (var i = 0; i < 3; i++) grid.ColumnDefinitions.Add(new ColumnDefinition {Width = new GridLength(1, GridUnitType.Auto)});

grid.RowDefinitions.Clear();
for (var i = 0; i < 2; i++) grid.RowDefinitions.Add(new RowDefinition {Height = new GridLength(1, GridUnitType.Auto)});

foreach (var widget in new UIElement[] {lblFruit, txtFruit, btnAdd, lblBasket, lstBasket, btnDelete}) grid.Children.Add(widget); dlg = new Window {Title = "Fruit Basket", Content = grid, SizeToContent = SizeToContent.WidthAndHeight, HorizontalAlignment = HorizontalAlignment.Center, VerticalAlignment = VerticalAlignment.Center};
}
else {
var panelAdd = new StackPanel {Orientation = Orientation.Horizontal};
foreach (var widget in new UIElement[] {lblFruit, txtFruit, btnAdd}) panelAdd.Children.Add(widget);

var panelDelete = new StackPanel {Orientation = Orientation.Horizontal};
foreach (var widget in new UIElement[] {lblBasket, lstBasket, btnDelete}) panelDelete.Children.Add(widget);

var panelMain = new StackPanel {Orientation = Orientation.Vertical};
foreach (var widget in new UIElement[] {panelAdd, panelDelete}) panelMain.Children.Add(widget);

dlg = new Window {Title = "Fruit Basket", Content = panelMain, SizeToContent = SizeToContent.WidthAndHeight, HorizontalAlignment = HorizontalAlignment.Center, VerticalAlignment = VerticalAlignment.Center};
}

// Define closing event handler
dlg.Closing += (o, e) => e.Cancel = (MessageBox.Show("Close program?", "Confirm", MessageBoxButton.YesNo) == MessageBoxResult.No);

// Finalize dialog
txtFruit.Focus();

var bUseApplication = true;
// bUseApplication = false;
if (bUseApplication) {
var app = new FruitBasket();
app.Run(dlg);
}
else dlg.ShowDialog();
} // Main method
} // FruitBasket class

// End of wpf_fruit.cs


'content of wpf_fruit.vb
'Fruit Basket program in Visual Basic 10 with Windows Presentation Foundation
'Public domain by Jamal Mazrui
'June 8, 2010

Option Explicit On
Option Strict On

' Import namespaces
Imports System.Windows
Imports System.Windows.Controls

' Define class
Class FruitBasket
Inherits Application

' Define entry point of program
<STAThread> Shared Sub Main()

' Create controls;
Dim txtFruit = New TextBox()
Dim lblFruit = New Label With {.Content = "_Fruit:", .Target = txtFruit }
Dim btnAdd = New Button With { .Content = "_Add", .IsDefault = True }
Dim lstBasket = New ListBox()
Dim lblBasket = New Label With { .Content = "_Basket:", .Target = lstBasket }
Dim btnDelete = New Button With { .Content = "_Delete" }

' Define Add event handler;
AddHandler btnAdd.Click, Sub()
Dim sFruit = txtFruit.Text.Trim()
If sFruit = "" Then
MessageBox.Show("No fruit to add!", "Alert")
Else
lstBasket.Items.Add(sFruit)
txtFruit.Clear()
lstBasket.SelectedIndex = lstBasket.Items.Count - 1
End If
End Sub

' Define Delete event handler;
AddHandler btnDelete.Click, Sub()
Dim iFruit = lstBasket.SelectedIndex
If iFruit = -1 Then
MessageBox.Show("No fruit to delete!", "Alert")
Else
lstBasket.Items.RemoveAt(iFruit)
If iFruit = lstBasket.Items.Count Then iFruit -= 1
lstBasket.SelectedIndex = iFruit
End If
End Sub

' Complete layout
Dim dlg As Window
Dim bUseGrid = True
' bUseGrid = false;
If bUseGrid Then
Dim grid = New Grid()
grid.ColumnDefinitions.Clear()
For i = 0 To 2
grid.ColumnDefinitions.Add(New ColumnDefinition With { .Width = New GridLength(1, GridUnitType.Auto) })
Next

grid.RowDefinitions.Clear()
For i = 0 To 1
grid.RowDefinitions.Add(New RowDefinition With { .Height = New GridLength(1, GridUnitType.Auto) })
Next

For Each widget In New UIElement() {lblFruit, txtFruit, btnAdd, lblBasket, lstBasket, btnDelete}
grid.Children.Add(widget)
Next

dlg = New Window With { .Title =
"Fruit Basket", .Content = grid, .SizeToContent = SizeToContent.WidthAndHeight, .HorizontalAlignment = HorizontalAlignment.Center, .VerticalAlignment = VerticalAlignment.Center }
Else
Dim panelAdd = New StackPanel With { .Orientation = Orientation.Horizontal }
For Each widget In New UIElement() {lblFruit, txtFruit, btnAdd}
panelAdd.Children.Add(widget)
Next

Dim panelDelete = New StackPanel With {.Orientation = Orientation.Horizontal}
For Each widget In New UIElement() {lblBasket, lstBasket, btnDelete}
panelDelete.Children.Add(widget)
Next

Dim panelMain = New StackPanel With {.Orientation = Orientation.Vertical}
For Each widget In New UIElement() {panelAdd, panelDelete}
panelMain.Children.Add(widget)
Next

dlg = New Window With {.Title = "Fruit Basket", .Content = panelMain, .SizeToContent = SizeToContent.WidthAndHeight, .HorizontalAlignment = HorizontalAlignment.Center, .VerticalAlignment = VerticalAlignment.Center}
End If

' Define closing event handler
AddHandler dlg.Closing, Sub(o, e)
If MessageBox.Show("Close program?", "Confirm", MessageBoxButton.YesNo) = MessageBoxResult.No Then e.Cancel = True
End Sub

' Finalize dialog
txtFruit.Focus()

Dim bUseApplication = True
' bUseApplication = false
If bUseApplication Then
Dim app = New FruitBasket()
app.Run(dlg)
Else
dlg.ShowDialog()
End If
End Sub
End Class
' End of wpf_fruit.vb
__________
View the list's information and change your settings at //www.freelists.org/list/programmingblind

Other related posts: