Showing posts with label Button. Show all posts
Showing posts with label Button. Show all posts

Friday, March 11, 2011

WrapPanel (CODE)

The panel most similar to StackPanel is WrapPanel. During the years that the Windows Presentation Foundation was being designed and created, the WrapPanel actually preceded the StackPanel. The WrapPanel displays rows or columns of elements and automatically wraps to the next row (or column) if there's not enough room. It sounds quite useful, but it turned out that developers were mostly using WrapPanel without the wrapping. These developers didn't know it at the time, but they really wanted a StackPanel.

WrapPanel is useful when you need to display an unknown number of items in a two-dimensional area. (Think of it as Windows Explorer in non-detail view.) It's likely that all these items will be the same size. WrapPanel doesn't require that, but it has ItemHeight and ItemWidth properties that you can use to enforce uniform height or width. The only other property that WrapPanel defines is Orientation, which you use the same way as for StackPanel.

It is difficult to imagine an application of WrapPanel that doesn't also involve ScrollViewer.  Lets see example with both:

//INSIDE CONSTRUCTOR OF WINDOWS
{
Title = "Explore Directories";

ScrollViewer scroll = new ScrollViewer();
Content = scroll;

WrapPanel wrap = new WrapPanel();
scroll.Content = wrap;

wrap.Children.Add(new FileSystemInfoButton());
}


I named FileSystemInfoButton for the FileSystemInfo object in System.IO. The two classes that derive from FileSystemInfo are FileInfo and DirectoryInfo. If you have a particular object of type FileSystemInfo, you can determine whether it refers to a file or to a directory by using the is operator.

The FileSystemInfoButton class derives from Button and stores a FileSystemInfo object as a field. The class has three constructors. The single-argument constructor is the one used most. It requires an argument of type FileSystemInfo, which it stores as a field. The constructor sets the button's Content to the Name property of this object. That's either the name of a directory or the name of a file. If this object is a DirectoryInfo, the text is bolded.

The parameterless constructor is used only when the program starts up and the window adds the first child to the WrapPanel or any other panel. The parameterless constructor passes a DirectoryInfo object for the My Documents directory to the single-argument constructor.


 


//////Contd////

Putting multiple elements into buttons

The following program creates a single button, but the button contains a StackPanel that has four children: an Image, a Label, and two Polyline objects. (Polyline inherits from Shape.)

Title = "Design a Button";

// Create a Button as content of the

Button btn = new Button();
btn.HorizontalAlignment =HorizontalAlignment.Center;
btn.VerticalAlignment =VerticalAlignment.Center;
btn.Click += ButtonOnClick;
Content = btn;

// Create a StackPanel as content of button
StackPanel stack = new StackPanel();
btn.Content = stack;

// Add a Polyline to the StackPanel.
stack.Children.Add(ZigZag(10));

// Add an Image to the StackPanel.
Uri uri = new Uri("pack://application:,,books.ICO"); // 32-pixels
BitmapImage bitmap = new BitmapImage(uri);
Image img = new Image();
img.Margin = new Thickness(0, 10, 0, 0);
img.Source = bitmap;
img.Stretch = Stretch.None;
stack.Children.Add(img);

// Add a Label to the StackPanel.
Label lbl = new Label();
lbl.Content = "_Read books!";
lbl.HorizontalContentAlignment =HorizontalAlignment.Center;
stack.Children.Add(lbl);

// Add another Polyline to the stackpanel
stack.Children.Add(ZigZag(0));

}

Polyline ZigZag(int offset)
{
Polyline poly = new Polyline();
poly.Stroke = SystemColors.ControlTextBrush;
poly.Points = new PointCollection();

for (int x = 0; x <= 100; x += 10)
poly.Points.Add(new Point(x, (x +offset)% 20));
return poly;
}

void ButtonOnClick(object sender,RoutedEventArgs args)
{
MessageBox.Show("The button has been clicked", Title);
}

Tuesday, March 8, 2011

Toggle Buttons

Both CheckBox and RadioButton are considered types of "toggle" buttons, as is clear from a complete view of the classes that descend from ButtonBase:

Control
--ContentControl
------ButtonBase (abstract)
------------Button
-------------GridViewColumnHeader
-------------RepeatButton
-------------ToggleButton
---------------------CheckBox
---------------------RadioButton

ToggleButton is not abstract, so you can also create an object of type ToggleButton, which looks just like a regular button except that it toggles on and off.

Consider the example :

ToggleButton btn = new ToggleButton();
btn.Content = "Can _Resize";
btn.HorizontalAlignment =HorizontalAlignment.Center;
btn.VerticalAlignment =VerticalAlignment.Center;
//win is the Window reference in which toggle button lies
btn.IsChecked = (win.ResizeMode ==ResizeMode.CanResize);
btn.Checked += ButtonOnChecked;
btn.Unchecked += ButtonOnChecked;

//Event handler ButtonOnChecked
void ButtonOnChecked(object sender,RoutedEventArgs args)
{
ToggleButton btn = sender as ToggleButton;
win.ResizeMode = (bool)btn.IsChecked ? ResizeMode.CanResize : ResizeMode.NoResize;
}



ToggleTheButton uses the button to switch the ResizeMode property of the window between ResizeMode.CanResize and ResizeMode.NoResize. The button automatically toggles itself on and off as the user clicks it. The IsChecked property indicates the current setting. Notice that the program initializes IsChecked to true if ResizeMode is initially ResizeMode.CanResize and false otherwise. Two events named Checked and Unchecked are triggered as the button is checked and unchecked. You can attach the same event handler to both events and simply use the IsChecked property to distinguish them, which is exactly what ToggleTheButton does.

Notice that the IsChecked property must be cast to a bool before being used in the C# conditional operator. The IsChecked property is actually a nullable bool, and can take on values of true, false, and null. If you set the IsThreeState property of ToggleButton to true, you can set IsChecked to null to display a third, "indeterminate" state of the button. For example, an Italic button in a word processing program might use this indeterminate state if the currently selected text has a mix of both italic and non-italic characters. (However, if the currently selected text is in a font that doesn't allow italics, the program would disable the Italic button by setting its IsEnabled property to false.)

The CheckBox class adds almost nothing to ToggleButton. You can create a CheckBox in this program just by replacing the button creation code with this:

CheckBox btn = new CheckBox();



 

 

You don't need to change the event handler. The program works the same except that the button looks different. You could also change ToggleTheButton's button to a RadioButton, but the program wouldn't work properly. You cannot uncheck a radio button by manually clicking it.

Because a ToggleButton or a CheckBox essentially represents the value of a Boolean, it makes sense that a particular toggle button be associated with a Boolean property of some object. This is called data binding, and it is such an important part of the Windows Presentation Foundation that Chapter 23 is devoted to the topic.

A ToggleButton used with data binding doesn't need to have its IsChecked property initialized, or have handlers installed for the Checked and Unchecked events. What's required instead is a call to the SetBinding method, which the button inherits from the FrameworkElement class. For a ToggleButton or CheckBox object, the call is typically something like this:

btn.SetBinding(ToggleButton.IsCheckedProperty, "SomeProperty");


where the second argument is a string with the name of a property you want associated with the IsChecked state of the button. You specify the object that "SomeProperty" belongs to with the DataContext property of Button.

The first argument to the SetBinding method probably looks even stranger than the second argument. It refers not to the IsChecked property of a ToggleButton object, but instead to something called IsCheckedProperty that appears to be a static member of the ToggleButton class.

ToggleButton does indeed define a static field named IsCheckedProperty that is an object of type DependencyProperty. Chapter 8 is devoted in its entirety to dependency properties. For now, think of it just as a convenient way to refer to a particular property defined by ToggleButton.

So, to what Boolean property do we want to bind the ToggleButton? One convenient Boolean is the Topmost property of the window. As you'll recall, if Topmost is set to true, the window always appears in the foreground of other windows. The SetBinding call looks like this:

btn.SetBinding(ToggleButton.IsCheckedProperty, "Topmost");


The data binding won't try to guess which object in the program is the one whose Topmost property you're referring to, so you need to specify that object by setting the DataContext property of the button to the window object:

btn.DataContext = this;