programming4us
programming4us
MULTIMEDIA

Building a WPF Application without XAML (part 2)

- How To Install Windows Server 2012 On VirtualBox
- How To Bypass Torrent Connection Blocking By Your ISP
- How To Install Actual Facebook App On Kindle Fire
10/18/2011 9:08:08 AM

3. Interacting with Application Level Data

Recall that the Application class defines a property named Properties, which allows you to define a collection of name/value pairs via a type indexer. Because this indexer has been defined to operate on type System.Object, you are able to store any sort of item within this collection (including your custom classes), to be retrieved at a later time using a friendly moniker. Using this approach, it is simple to share data across all windows in a WPF application.

To illustrate, you will update the current Startup event handler to check the incoming command-line arguments for a value named /GODMODE (a common cheat code for many PC video games). If you find this token, you will establish a bool value set to true within the properties collection of the same name (otherwise you will set the value to false).

Sounds simple enough, but how are you going to pass the incoming command-line arguments (typically obtained from the Main () method) to your Startup event handler? One approach is to call the static Environment.GetCommandLineArgs() method. However, these same arguments are automatically added to the incoming StartupEventArgs parameter and can be accessed via the Args property. That being said, here is the first update to the current code base:

private static void AppStartUp(object sender, StartupEventArgs e)
{
// Check the incoming command-line arguments and see if they
// specified a flag for /GODMODE.
Application.Current.Properties["GodMode"] = false;
foreach(string arg in e.Args)
{
if (arg.ToLower() == "/godmode")
{
Application.Current.Properties["GodMode"] = true;
break;
}
}

// Create a MainWindow object.
MainWindow wnd = new MainWindow("My better WPF App!", 200, 300);
}

Application-wide data can be accessed from anywhere within the WPF application. All you are required to do is obtain an access point to the global application object (via Application.Current) and investigate the collection. For example, you could update the Click event handler of the Button as so:

private void btnExitApp_Clicked(object sender, RoutedEventArgs e)
{
// Did user enable /godmode?
if((bool)Application.Current.Properties["GodMode"])
MessageBox.Show("Cheater!");

this.Close();
}

With this, if the end user launches our program as follows:

WpfAppAllCode.exe /godmode

he or she will see our shameful message box displayed when terminating the application.

NOTE

Recall that you can supply command line arguments within Visual Studio. Simply double click on the Properties icon within Solution Explorer, click the Debug tab from the resulting editor, and enter /godmode within the "Command line arguments" editor.

4. Handling the Closing of a Window Object

End users can shut down a window using numerous built-in system-level techniques (e.g., clicking the "X" close button on the window's frame) or by indirectly calling the Close() method in response to some user interaction element (e.g., File => Exit). In either case, WPF provides two events that you can intercept to determine if the user is truly ready to shut down the window and remove it from memory. The first event to fire is Closing, which works in conjunction with the CancelEventHandler delegate.

This delegate expects target methods to take System.ComponentModel.CancelEventArgs as the second parameter. CancelEventArgs provides the Cancel property, which when set to true will prevent the window from actually closing (this is handy when you have asked the user if he really wants to close the window or if perhaps he would like to save his work first).

If the user did indeed wish to close the window, CancelEventArgs.Cancel can be set to false. This will then cause the Closed event to fire (which works with the System.EventHandler delegate), making it the point at which the window is about to be closed for good.

Update the MainWindow class to handle these two events by adding these code statements to the current constructor:

public MainWindow(string windowTitle, int height, int width)
{
...
this.Closing += MainWindow_Closing;
this.Closed += MainWindow_Closed;
}

Now, implement the corresponding event handlers as so:

private void MainWindow_Closing(object sender,
System.ComponentModel.CancelEventArgs e)
{
// See if the user really wants to shut down this window.
string msg = "Do you want to close without saving?";
MessageBoxResult result = MessageBox.Show(msg,
"My App", MessageBoxButton.YesNo, MessageBoxImage.Warning);

if (result == MessageBoxResult.No)
{
// If user doesn't want to close, cancel closure.
e.Cancel = true;
}
}

private void MainWindow_Closed(object sender, EventArgs e)

{
MessageBox.Show("See ya!");
}

Now, run your program and attempt to close the window, either by clicking the "X" icon on the upper right of the window or by clicking the button control. You should see the following confirmation dialog (Figure 2).

Figure 2. Trapping the Closing event of a Window

If you click the Yes button, the application will terminate; however, clicking the No button will keep the window in memory.

5. Intercepting Mouse Events

The WPF API provides a number of events you can capture in order to interact with the mouse. Specifically, the UIElement base class defines a number of mouse-centric events such as MouseMove, MouseUp, MouseDown, MouseEnter, MouseLeave, and so forth.

Consider, for example, the act of handling the MouseMove event. This event works in conjunction with the System.Windows.Input.MouseEventHandler delegate, which expects its target to take a System.Windows.Input.MouseEventArgs type as the second parameter. Using MouseEventArgs (like a Windows Forms application), you are able to extract out the (x, y) position of the mouse and other relevant details. Consider the following partial definition:

public class MouseEventArgs : InputEventArgs
{
...
public Point GetPosition(IInputElement relativeTo);
public MouseButtonState LeftButton { get; }
public MouseButtonState MiddleButton { get; }
public MouseDevice MouseDevice { get; }
public MouseButtonState RightButton { get; }
public StylusDevice StylusDevice { get; }
public MouseButtonState XButton1 { get; }
public MouseButtonState XButton2 { get; }
}

NOTE

The XButton1 and XButton2 properties allow you to interact with "extended mouse buttons" (such as the "next" and "previous" buttons found on some mouse controls). These are often used to interact with a browser's history list to navigate between visited pages.

The GetPosition() method allows you to get the (x, y) value relative to a UI element on the window. If you are interested in capturing the position relative to the activated window, simply pass in this. Handle the MouseMove event in the constructor of your MainWindow class like so:

public MainWindow(string windowTitle, int height, int width)
{
...
this.MouseMove += MainWindow_MouseMove;
}

Here is an event handler for MouseMove that will display the location of the mouse in the window's title area (notice you are translating the returned Point type into a text value via ToString()):

private void MainWindow_MouseMove(object sender,
System.Windows.Input.MouseEventArgs e)
{
// Set the title of the window to the current X,Y of the mouse.
this.Title = e.GetPosition(this).ToString();
}

6. Intercepting Keyboard Events

Processing keyboard input is also very straightforward. UIElement defines a number of events that you can capture to intercept keypresses from the keyboard on the active element (e.g., KeyUp, KeyDown). The KeyUp and KeyDown events both work with the System.Windows.Input.KeyEventHandler delegate, which expects the target's second event handler to be of type KeyEventArgs, which defines several public properties of interest:

public class KeyEventArgs : KeyboardEventArgs
{
...
public bool IsDown { get; }
public bool IsRepeat { get; }
public bool IsToggled { get; }
public bool IsUp { get; }
public Key Key { get; }
public KeyStates KeyStates { get; }
public Key SystemKey { get; }
}

To illustrate handling the KeyDown event in the constructor of MainWindow (just like you did for the previous events) and implement the following event handler that changes the content of the button with the currently pressed key, use this code:

private void MainWindow_KeyDown(object sender, System.Windows.Input.KeyEventArgs e)
{
// Display key press on the button.
btnExitApp.Content = e.Key.ToString();
}


As a finishing touch, double click on the Properties icon of the Solution Explorer, and under the Application tab, set the Output Type setting to Windows Application. This will prevent the console window from launching in the background of your WPF application. Figure 3 shows the final product of your first WPF program.

Figure 3. Your first WPF program, 100% XAML free

Other  
 
Top 10
- Microsoft Visio 2013 : Adding Structure to Your Diagrams - Finding containers and lists in Visio (part 2) - Wireframes,Legends
- Microsoft Visio 2013 : Adding Structure to Your Diagrams - Finding containers and lists in Visio (part 1) - Swimlanes
- Microsoft Visio 2013 : Adding Structure to Your Diagrams - Formatting and sizing lists
- Microsoft Visio 2013 : Adding Structure to Your Diagrams - Adding shapes to lists
- Microsoft Visio 2013 : Adding Structure to Your Diagrams - Sizing containers
- Microsoft Access 2010 : Control Properties and Why to Use Them (part 3) - The Other Properties of a Control
- Microsoft Access 2010 : Control Properties and Why to Use Them (part 2) - The Data Properties of a Control
- Microsoft Access 2010 : Control Properties and Why to Use Them (part 1) - The Format Properties of a Control
- Microsoft Access 2010 : Form Properties and Why Should You Use Them - Working with the Properties Window
- Microsoft Visio 2013 : Using the Organization Chart Wizard with new data
REVIEW
- First look: Apple Watch

- 3 Tips for Maintaining Your Cell Phone Battery (part 1)

- 3 Tips for Maintaining Your Cell Phone Battery (part 2)
programming4us programming4us
programming4us
 
 
programming4us