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

#202 – An Example of Modal/Modeless Dialogs

You can see an example of both modal and modeless dialogs if you run the Windows Notepad application.

After starting the Notepad application, enter some text and then bring up the Find dialog using Edit | Find.  You’ll notice that you can switch back and forth between the Find dialog and the main Notepad window.  The Find dialog is a modeless dialog, since you can still interact with the main application.

Now close the Find dialog and open the Print dialog using File | Print.  While the Print dialog is open, you’ll notice that you can no longer interact with the main Notepad window.  The Print dialog is a modal dialog.

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

#198 – Creating and Showing Additional Windows

You can create and show additional Window objects at runtime–in addition to your application’s main window.

Let’s assume that we want a second type of window in our application, beyond the MainWindow class that the WPF Application wizard creates for us.  To start with, right-click in the Solution Explorer and select Add, New Item.

In the dialog, that comes up, select WPF as the template group and then Window (WPF) as the object to add.  Give the new window a name.

It will now show up in the Solution Explorer.

Finally, to create and show the new window, you just create an instance of the new class and call its Show method.  For example, we might add a Button on the main form that creates a new window whenever you click on it.

    private void Button_Click(object sender, System.Windows.RoutedEventArgs e)
    {
        AnotherWindow win = new AnotherWindow();
        win.Show();
    }

#197 – Override Application Class Methods for Standard Events

We’ve already mentioned some of the main events that the Application class fires–e.g. Startup, Exit and SessionEnding.  We also showed how you can add event handlers to your Application-derived class to handle these events, using SessionEnding as our example.

Rather than adding an event handler for Application.SessionEnding to our class, we could have just overridden the OnSessionEnding method.  This is more appropriate in a class that already derives from Application.  Instead of specifying the handler in App.xaml and adding the handler to App.xaml.cs, we can just add code for the override to App.xaml.cs.

As an example, the override for OnSessionEnding could look something like this:

	public partial class App : Application
	{
            protected override void OnSessionEnding(SessionEndingCancelEventArgs e)
            {
                // Always call method in base class, so that the event gets raised.
                base.OnSessionEnding(e);

                // Place your own SessionEnding logic here
            }
    }
Follow

Get every new post delivered to your Inbox.

Join 375 other followers