#283 – A Window Can Have Only a Single Child Element

In WPF, a Window can have only a single child element.  Window inherits from ContentControl, which is a control that contains a single child element, referenced by its Content property.

Your window might have a single simple child control, like a Button.

<Window>
	<Button Content="Big Daddy Button"/>
</Window>

Since having a single control in your application is not very useful, it’s more common that the single child control of a Window is a container control like StackPanel, which in turn can contain multiple child elements.

<Window>
	<StackPanel>
		<Label Content="You can enter your name here:"/>
		<TextBox />
		<Button Content="Push to Continue"/>
	</StackPanel>
</Window>

#272 – Displaying a Border Around a Window

You can include a border around the edges of a Window using the BorderBrush and BorderThickness properties.

By default, the BorderBrush is null and BorderThickness is a Thickness structure with all of its dimensions set to 0.

If you specify only the BorderThickness property, you get a black border around the window.

<Window
	 BorderThickness="5,10,5,10">

You can also specify both a border brush and a border thickness.

<Window
	 BorderThickness="20">

	<Window.BorderBrush>
	 	<LinearGradientBrush>
            <GradientStop Color="DarkKhaki" Offset="0.0"/>
            <GradientStop Color="DarkGreen" Offset="1.0"/>
        </LinearGradientBrush>
	</Window.BorderBrush>

#271 – Changing a Window’s Resize Behavior

There are four different options for allowing a window to be resized.  You set the resizing behavior using the ResizeMode property.

The default value for ResizeMode is CanResize.  This results in the standard window border, allowing resizing by dragging the edge of the window.

<Window
	Width="300" Height="150" ResizeMode="CanResize">


The CanResizeWithGrip option is similar to CanResize, but the lower right corner of the window shows a little “grip” icon indicating that you can “grab” the window here to resize it.

<Window
	Width="300" Height="150" ResizeMode="CanResizeWithGrip">


The NoResize option creates a window that can’t be resized, minimized or maximized.  Notice that the minimize and maximize buttons have also disappeared.

<Window
	Width="300" Height="150" ResizeMode="NoResize">


The final choice for ResizeMode is CanMinimize, which creates a window that can’t be resized or maximized, but can be minimized.

<Window
	Width="300" Height="150" ResizeMode="CanMinimize">

#270 – Minimum and Maximum Window Size

By default, there are no upper or lower limits for the size of a window in WPF–you can shrink a window to the point where none of its content is visible and you can maximize a window so that it takes up the entire desktop.

You can use the MinWidth and MinHeight properties to dictate the minimum dimensions for the window.  When resizing the window, you’ll be unable to make the window any smaller.

<Window
	Width="400" Height="300" MinHeight="100" MinWidth="200">


You can use the MaxWidth and MaxHeight properties to dictate the maximum dimensions for the window.  When resizing the window, you’ll be unable to make the window any larger.  If you try maximizing the window, it will be constrained to the maximum size.

<Window
	Width="400" Height="300" MaxWidth="500" MaxHeight="320">

#269 – Automatically Sizing a Window to Fit Its Contents

You normally set the width and height of a WPF Window by setting its Width and Height properties directly.

<Window Width="400" Height="300" >

At runtime, this sets the starting window size.

If you want the window to automatically size to fit its contents, you can set the SizeToContent property.  By default, this property has a value of Manual, indicating that the Width and Height properties will dictate the window’s size.  (Ignoring the effect of min/max properties).

Setting SizeToContent to Height will force the window to adjust its height to fit the contents.

<Window Width="400" Height="300" SizeToContent="Height">

Setting SizeToContent to Width will force the window to adjust its width to fit the contents.

<Window Width="400" Height="300" SizeToContent="Width">


And setting it to WidthAndHeight will tell the window to adjust both dimensions.

<Window Width="400" Height="300" SizeToContent="Width">

#204 – Detecting Key Presses in a WPF Window

You can detect key presses in a class that derives from Window by overriding the OnKeyDown and OnKeyUp methods (which in turn fire the KeyDown and KeyUp events).  

These key down/up methods are invoked in addition to any control that has focus and might also provide key down/up methods.

For example, a TextBox also has KeyDown and KeyUp events that are fired.  If a user presses a key while a TextBox has focus, the sequence of events is:

  • KeyDown in TextBox
  • KeyDown in Window
  • KeyUp in TextBox
  • KeyUp in Window

Here’s an example:

    public partial class MainWindow : Window
    {
        private static Key[] vowels = { Key.A, Key.E, Key.I, Key.O, Key.U };

        protected override void OnKeyDown(KeyEventArgs e)
        {
            base.OnKeyDown(e);

            if ((vowels.Contains(e.Key)) && (!e.IsRepeat))
                lblVowels.Content = lblVowels.Content + e.Key.ToString();
        }

        protected override void OnKeyUp(KeyEventArgs e)
        {
            base.OnKeyUp(e);

            if (vowels.Contains(e.Key))
                lblVowels.Content = lblVowels.Content + ",";
        }

#203 – Window Size and Location Are Specified in Device Independent Units

The Window class has Left and Top properties that specify the location on the screen of the left and top sides of the window.  It also has Width and Height properties that specify the window’s size.  All of these are expressing in device independent units.

If the current DPI setting is 96 dpi (dots per inch), the WPF units are equivalent to pixels.  I.e. A window specified as 96 units high would appear as 1 inch high.  If the DPI setting is different, the specified WPF units are scaled by dpi/96 to get the resulting pixel value.

In other words:    # pixels = (# WPF Units) * (DPI / 96)

The reason for this is so that WPF applications will appear at roughly the same dimensions on various monitors, regardless of the pixel density.

#201 – Showing a Modal Dialog Using ShowDialog

Rather than using the Window.Show method to show a modeless window, you can use the ShowDialog method to show the window as a modal dialog.

A modal dialog is one that appears in front of all other windows in the application and blocks interaction with all the other windows until the modal dialog is closed.

A modeless window, on the other hand, is one that you can interact with along with other windows in the application.

In the example below, we use the same child window class, but display one window as modeless (using Show) and one as modal (using ShowDialog).

        private void btnModal_Click(object sender, RoutedEventArgs e)
        {
            ChildWindow win = new ChildWindow();
            win.Title = "Modal child - " + DateTime.Now.ToLongTimeString();
            win.ShowDialog();
        }

        private void btnModeless_Click(object sender, RoutedEventArgs e)
        {
            ChildWindow win = new ChildWindow();
            win.Title = "Modeless window - " + DateTime.Now.ToLongTimeString();
            win.Show();
        }

Minimizing a modal window will also minimize its parent.

#200 – Parent/Child Relationships Between Windows

Creating a new Window object and displaying it using the Show method results in a new window in your application that is independent from any existing windows.  The new window can be minimized and maximized independently and gets its own icon on the taskbar.

Creating a new (independent) window:

    Window w = new Window();
    w.Title = DateTime.Now.ToLongTimeString();
    w.Show();

WPF supports the notion of parent/child relationships between windows.  You set up the relationship by setting the Owner property of the child window to point to the parent.

    Window w = new Window();
    w.Title = string.Format("Child #{0}", this.OwnedWindows.Count + 1);
    w.Owner = this;
    w.Show();

When you make one window the child of another:

  • When a parent is minimized, all the child windows are minimized
  • When child is minimized, parent is not minimized
  • You can interact with either window
  • The parent can’t cover a child window
  • Closing a parent closes all the child windows

#199 – An Application’s Windows Property Lists All of Its Windows

The Application class has a Windows property which is a collection of all of the windows that have been created by the current application.

Assume that we have an application with a main window that includes the following two buttons:

Whenever the user clicks on the Create New Window button, we create and show a new window.

    private void btnCreate_Click(object sender, System.Windows.RoutedEventArgs e)
    {
        AnotherWindow win = new AnotherWindow();
        win.Title = DateTime.Now.ToLongTimeString();
        win.Show();
    }

In the Click event handler for the Where Are the Windows? button, we can iterate through all of the windows that the application created and display some information about each one.

        private void btnWhere_Click(object sender, RoutedEventArgs e)
        {
            StringBuilder sb = new StringBuilder();
            foreach (Window w in App.Current.Windows)
            {
                sb.AppendFormat("Window [{0}] is at ({1},{2}).\n", w.Title, w.Top, w.Left);
            }

            MessageBox.Show(sb.ToString(), "My Windows");
        }

The final result:

Follow

Get every new post delivered to your Inbox.

Join 228 other followers