Wednesday, March 9, 2011

StackPanel (Code)

As discussed here, we now discuss StackPanel programatically :

The following program sets the Content property of its window to a StackPanel and then creates 10 buttons that become children of the panel.
StackPanel stack = new StackPanel();
Content = stack;
Random rand = new Random();

for (int i = 0; i < 10; i++)
{
Button btn = new Button();
btn.Name = ((char)('A' + i)).ToString();
btn.FontSize += rand.Next(10);
btn.Content = "Button " + btn.Name + " says 'Click me'";
btn.Click += ButtonOnClick;
stack.Children.Add(btn);
}

Layout (Code)

Controls that derive from the ContentControl class (such as Window, Button, Label, and ToolTip) have a property named Content that you can set to almost any object. Commonly, this object is either a string or an instance of a class that derives from UIElement. The problem is you can set Content to only one object, which may be satisfactory for simple buttons, but is clearly inadequate for a window.
Fortunately, the Windows Presentation Foundation includes several classes designed specifically to alleviate this problem. These are collectively known as panels, and the art and science of putting controls and other elements on the panel is known as layout.
Panels derive from the Panel class. This partial class hierarchy shows the most important derivatives of Panel:
UIElement
    FrameworkElement
         Panel (abstract)
                Canvas
                DockPanel
                Grid
                StackPanel
                UniformGrid
                WrapPanel
The panel is a relatively recent concept in graphical windowing environments. Traditionally, a Windows program populated its windows and dialog boxes with controls by specifying their precise size and location. The Windows Presentation Foundation, however, has a strong commitment to dynamic layout (also known as automatic layout). The panels themselves are responsible for sizing and positioning elements based on different layout models. That's why a variety of classes derive from Panel: Each supports a different type of layout.
Panel defines a property named Children used to store the child elements. The Children property is an object of type UIElementCollection, which is a collection of UIElement objects. Thus, the children of a panel can be Image objects, Shape objects, TextBlock objects, and Control objects, just to mention the most popular candidates. The children of a panel can also include other panels. Just as you use a panel to host multiple elements in a window, you use a panel to host multiple elements in a button or any other ContentControl object.

Although automatic layout is a crucial feature in the Windows Presentation Foundation, you can't use it in a carefree way. Almost always, you'll have to use your own aesthetic sense in tweaking certain properties of the elements, most commonly HorizontalAligment, VerticalAlignment, Margin, and Padding.
Looking at them 1 by 1: 
StackPanel

File Open and File Save dialog boxes


RichTextBox

The RichTextBox is much more complex than the TextBox because it stores text that could have a variety of different character and paragraph formatting. If you're familiar with previous Windows controls similar to RichTextBox, you might naturally assume that the control stores text in the Rich Text Format (RTF), a file format that dates from the mid-1980s and which was intended to provide an interchange format among word processing programs. The WPF version of RichTextBox certainly supports RTF (and plain text as well) but it also supports an XML-based file format that is a subset of the Extensible Application Markup Language (XAML) supported by WPF.

Formatted text gets into and out of the RichTextBox through the Document property. This Document property is of type FlowDocument, and the following code creates a TextRange object that encompasses the entire document:

TextRange range = new TextRange(flow.ContentStart, flow.ContentEnd);
The TextRange class defines two methods named Load and Save. The first argument is a Stream; the second is a string describing the desired data format. For this second argument it's easiest to get those strings from static members of the DataFormats class. With the RichTextBox, you can use DataFormats.Text, DataFormats.Rtf, DataFormats.Xaml, and DataFormats.XamlPackage, which is actually a ZIP file that contains binary resources the document might require. This program is hard-coded to use DataFormats.Xaml. (The program can't load any arbitrary XAML file, however.) You may want to look at these files to get a glimpse of the format of documents under the Windows Presentation Foundation.


TextBox and RichTextBox (Code)

Speaking of the TextBox control, the Windows Presentation Foundation supports the two we've come to expect:
Control
       TextBoxBase (abstract)
                  TextBox
                  RichTextBox
Although the TextBox has content, it is not considered a ContentControl because the content is always text. Instead it has a Text property that lets you set an initial string or obtain the string that the user typed.
Because TextBox derives from Control, you can specify the background and foreground brushes used in the control, as well as the font. However, at any time, all the text that appears in a particular TextBox will always be the same color and use the same font. The RichTextBox control lets the program (and the user) apply various character and paragraph formatting to different parts of the text. The difference between TextBox and RichTextBox is the same as the difference between Windows Notepad and Windows WordPad.
By default, a TextBox control allows entry of a single line of text.

By default the TextBox isn't interested in the Enter key. If you set :
Label lbl = new Label();
lbl.Content = "File _name:";
The single-line edit control becomes a multiline edit control and now handles carriage returns.

Label (Code)

Traditionally the Label control has been the standard way to display short text strings in forms and dialog boxes. For example, here's a label that might appear in a File Open dialog:

Label lbl = new Label();
lbl.Content = "File _name:"; 
 
With versatile elements such as TextBlock, the Label control would seem to be obsolete, but it's really not, and the key to its longevity is the ability to use underscores in text that you assign to the Content property. In a File Open dialog box, pressing Alt+N shifts the input focus not to the labelbecause labels are commonly non-focusablebut to the control after the label, which is probably a TextBox control that lets the user enter and edit text. Thus, labels continue to maintain their role as assistants in keyboard navigation.


ToolTip property

The BindTheButton program also includes a ToolTip object that is set to the ToolTip property of the Button. The text appears when the mouse cursor pauses over the button. The ToolTip property is defined by FrameworkElement, so you can attach a tooltip to other elements as well as controls. Like ButtonBase and Windows, ToolTip derives from ContentControl, so you can use formatted text in the ToolTip, and even pictures if you really want to mess with the heads of your users.
If you'd like to see a ToolTip with an image, go back to the ImageTheButton program and insert the following four lines at the end of the constructor:
Button btn = new Button();
btn.Content = "Don't Click Me!";
ToolTip tip = new ToolTip();
tip.Content = img;
btn.ToolTip = tip;