#1,069 – Main Window Initially Has Keyboard Focus

When you first start a WPF application which contains elements that can get keyboard focus (e.g. TextBox), it’s the main Window that has the keyboard focus when the application starts.

We can see this by using code that reports the current keyboard focus within a Label at the bottom of the window.

1069-001

If we attach an event handler to the main Window for the TextInput event and use the handler to log information about the event, we can start typing after the window comes up and see that the Window is getting TextInput events based on what we type.  Nothing is rendered to the screen, but our logging indicates that TextInput events are being fired, with the main window as their source.

        private void Window_TextInput(object sender, TextCompositionEventArgs e)
        {
            Trace.WriteLine(string.Format("Window_TextInput: [{0}], source={1}", e.Text, e.Source.ToString()));
        }

1069-002

Advertisement

#837 – A Window Cannot Be a Child of a ContentControl

The content of a ContentControl can be just about anything, including either UI elements or simple CLR objects.  For example, the content of a CheckBox can be something more than a simple text string.

One of the few elements that cannot be used as content for a ContentControl is a Window.  It wouldn’t make sense to place a Window element as the content of something else, like a Button.  A Window can only be the topmost element of the logical tree.

If you do try to include a Window as a child of another element, you’ll get an exception at run-time, when the XAML is parsed.

    <Button Height="23" Width="80">
        <Window Title="A window in a button?" />
    </Button>

837-001

#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.