In my previous blog entry about notifications I mentioned that we had not covered the ResponseSubmitted event. Subscribing to this event allows you to respond to user input entered within a notification bubble. This blog entry discusses how you can capture and process user input within notifications.
Creating an HTML based form
The contents of a notification bubble is formatted using HTML. To request user input within a notification bubble we can utilise a HTML based form.
A simple form specified within HTML may look like the following example:
<form>
Name: <input name="name" /><br />
<input type="submit" />
</form>
Similar to a System.Windows.Forms base application there are a range of controls which can be used within an HTML based form. These controls are typically specified via an <input /> element, although there are some exceptions as shown in the following table:
Name |
HTML Syntax |
Hidden Field |
<input type="hidden" name="fieldname" value="default" /> |
Textbox (single line) |
<input type="text" name="fieldname" value="default" /> |
Textbox (single line password) |
<input type="password" name="fieldname" value="default" /> |
Textbox (multi line) |
<textarea name="fieldname" cols="40" rows="5">
default value
</textarea> |
Radio buttons |
<input type="radio" name="fieldname" value="1" />
<input type="radio" name="fieldname" value="2" />
<input type="radio" name="fieldname" value="3" /> |
Checkbox |
<input type="check" name="fieldname" checked="true" /> |
Combobox |
<select name="fieldname">
<option value="1">option 1</option>
<option value="2">option 2</option>
<option value="3">option 3</option>
</select> |
A sample form with two textbox controls could be specified within C# source code as follows:
Notification notif = new Notification();
notif.Text = @"<form>
Field 1: <input type=""text"" name=""fieldname1"" /><br />
Field 2: <input type=""text"" name=""fieldname2"" />
</form>";
Buttons
Using the controls specified above allows a notification to accept input from the user. However it does not provide the user with a mechanism to submit a completed form to the application for further processing.
A form is typically submitted when the user presses a submit button. A submit button can be specified within HTML via the use of an <input type=”submit” /> element. Whenever the user presses the submit button the ResponseSubmitted event will be triggered, allowing the form to be processed by the application.
Buttons can also be utilised within a notification to temporarily hide or permanently close a notification without submitting a form (useful for cancel or postpone style buttons etc). These actions can be specified via the use of button elements within the HTML as demonstrated below:
<!-- This button will minimise the notification -->
<input type="button" name="cmd:2" value="Hide" />
<!-- This button will permanently close the notification -->
<input type="button" name="something" value="Close" />
The value attribute contains the text displayed on the button, while the name (i.e. “cmd:2″) controls the action which occurs when the button is pressed. The name “cmd:2″ is a special value indicating to the operating system that the notification should be minimised and displayed as an icon that can be clicked to redisplay the notification. Having a button with any other name will cause the notification to permiantly be dismissed without the ResponseSubmitted event firing. All other “cmd:n” style button names are reserved by Microsoft for future use.
Hyperlinks
A HTML form can also contain traditional hyperlinks such as the following example:
<a href="help">Display further help</a>
Whenever such a link is pressed within the notification, the ResponseSubmitted event will trigger and the response string will be the string specified as the href attribute (”help” in this example).
Many of the built in operating system notifications utilise hyperlinks to provide access to settings or customisation dialogs.
Processing the response
When a HTML form within a notification is submitted the ResponseSubmitted event will trigger and this is the ideal opportunity for an application to process the contents of a form. TheResponseEventArgs parameter passed to this event handler contains a Response property that includes the current values of all fields within the form encoded in a format known as application/x-www-form-urlencoded.
Section 17.13.4 of the HTML 4.01 standard discusses application/x-www-form-urlencoded form data with the following description of the encoding process.
This is the default content type. Forms submitted with this content type must be encoded as follows:
- Control names and values are escaped. Space characters are replaced by `+’, and then reserved characters are escaped as described in [RFC1738], section 2.2: Non-alphanumeric characters are replaced by `%HH’, a percent sign and two hexadecimal digits representing the ASCII code of the character. Line breaks are represented as “CR LF” pairs (i.e., `%0D%0A’).
- The control names/values are listed in the order they appear in the document. The name is separated from the value by `=’ and name/value pairs are separated from each other by `&’.
As an example, if the form specified above contained the strings “Hello World” and “Good Bye” it would be encoded and appear within the Response property as follows:
?fieldname1=Hello+World&fieldname2=Good+Bye
The Microsoft documentation for the Response property contains an example of how to parse such response strings. It does this via some rather brittle string search and replace style operations. The sample code is not very generic, as it will break if you change the structure of your form even a little (such as renaming a field) and it does not deal with decoding hex escaped characters.
Within the sample application mentioned below I have implemented a function calledParseQueryString which performs the application/x-www-form-urlencoded decode process and returns a more easily used Dictionary of field control names to value mappings. This allows you to write a ResponseSubmitted event handler which looks something like the following:
private void notification1_ResponseSubmitted(object sender,
ResponseSubmittedEventArgs e)
{
// This dictionary contains a mapping between
// field names and field values.
Dictionary<string, string> controls = ParseQueryString(e.Response);
// Make use of the field values, in this case pulling the
// values out of the textboxes and displaying a message
// box.
MessageBox.Show(String.Format("first field = {0}, second field = {1}",
controls["fieldname1"], controls["fieldname2"]);
}
This should make the intention of the ResponseSubmitted event handler easier to determine, and makes for more easily maintained code. The “hard” part of the response parsing logic is now hidden away within the ParseQueryString function, leaving you with an easy to use collection of field values to play with.
Including images within a notification
Sometimes it is helpful to include a small image within a popup notification. This is possible, but as Keni Barwick found out, the syntax of your HTML has to be fairly precise for the notification balloon to locate the image (a similar situation to images within HTML help files).
You should have good success if you use the file:// protocol, and include a full path to your image using backward slashes to separate directories, i.e. use the format:
<img src="file:///path/to/image.bmp" />
For example to include the image \windows\alarm.bmp you would use the following HTML:
<img src="file:///windows/alarm.bmp" />
You could hard-code the path to your image file but this could cause problems if the user decides to install your application in a different location (on an SD card for example). If your images are stored in the same folder as your main executable you can determine the path to your images at runtime by using a function similar to the following code snippet:
using System.Reflection;
using System.IO;
public string GetPathToImage(string fileName)
{
// Determine the exe filename and path
Assembly assembly = Assembly.GetExecutingAssembly();
string executablePath = assembly.GetName().CodeBase;
// Trim off the exe filename from the path
executablePath = Path.GetDirectoryName(executablePath);
// Add the specified filename to the path
return Path.Combine(executablePath, fileName);
}
string imageURL = GetPathToImage("foo.bmp");
Sample Application
[Download notificationuserresponsesample.zip - 16KB]
A sample application is available for download. The sample demonstrates using a notification to specify the details of a pizza order. It also demonstrates the inclusion of an image within a notification.
When targeting a Windows Mobile 5.0 or above device, you could extend the sample by using thecustom soft keys feature mentioned in a previous blog entry to submit the notification by pressing a subkey instead of pressing a button within the body of the notification.
Please feel free to make use of the ParseQueryString method and any associated functionality within your own applications.
Share This