Password Safe is a .NET 2.0 Mobile application that allows you to keep your passwords in your mobile secured with the top secure AES encryption. It provides a nice touch surface with gestures, and can be completely used without a stylus, except when you're writing or editing new passwords.
First of all, when you download the exe, you just need to put the DLL and the exe file to any location of your choice. Then, you can start the exe after two security warnings. The password.pws file is optional, and can be placed in the “\My Documents” folder, and contains a demo database just to play around. This database has no password.
How to use Password Safe
The first time you start Password Safe, a welcome screen appears, and an empty default database is created. As the next step, you should create a password for it using the "Change Password" button. Then, you can select a category of passwords. After selecting a category, it appears empty, and you can use the "+" button on the header at the right to create a new one. Just type in a field. You'll notice that the Undo (blue button) and the Save button at the bottom get activated. Now, you can either undo your changes or save them. They are automatically saved when you log out or close Password Safe. If you want to delete a password, go to Details, press the "-" button on the header, and confirm the message dialog.
The Search button becomes active when you are are in a category list. You can minimize the contents of the list by opening the Search panel. In this panel, you can type like you type an SMS. Only those items that contain a part of the possible text you typed remain in the list.
If you want to minimize the choice of categories, click the "+" button on the header to add or remove categories. Don't worry if you remove a category. The passwords don't get lost and are still available in the "All Passwords" category, and you can add the category back to the list at any time.
In future releases I will add the possibility to create and edit our own categories. That's why the categories are all stored in the password.pws database.
In December, I bought a new mobile phone, the Xperia x1. Shortly before Christmas, I decided to quickly write a simple password safe to maintain the various passwords I own, both at job and at home. But as always, I could not write just simple programs, and so I wasn’t satisfied with the features that were available with the .NET Compact Framework for Windows Mobile. It didn’t like good, and it was hard to use without a stylus. Therefore, I decided to create my own fancy controls.
Due to the lack of a better name, I currently call them Fluid Controls, but most probably, I will rename them to a name that sounds good and is not already copyright protected. I guess iControl would not be possible ;-)
The controls that I developed are not windows components which are actually “windows”, and so they don’t have their own graphics and message system. They are more like Silverlight controls, which are completely maintained different.
The heart of the controls is the
It’s the connection between a Windows Form and the Fluid Controls. It listens to all events, like mouse or keyboard events, and translates them to send them to the controls. It also recognizes gestures.
As soon as a gesture is recognized, it sends an
OnGesture event to the root level controls (which will redirect them to their child controls, and so on). In this event, a control can decide to do something with this event, or to cancel this event.
The following snippet is from the
ScrollContainer class which is the base class for all controls that offer scrolling:
public override void OnGesture(GestureEventArgs e)
pressedGesture = e.Gesture;
e.Handled = true;
e.Gesture = Gesture.None;
e.Handled = true;
IsDown = false;
CanScroll = false;
e.Handled = true;
if (e.Distance > MinAutoScrollPixelDistance)
e.Handled = true;
int speed = e.PixelPerMs;
if (speed > 0) BeginAutoScroll(-speed);
if (e.Distance > MinAutoScrollPixelDistance)
e.Handled = true;
int speed = e.PixelPerMs;
if (speed > 0) BeginAutoScroll(speed);
if (MouseGesture != null) MouseGesture(this, e);
You can try the back gesture in Password Safe. Instead of pressing the Back button, you can wipe your finger from left to right and release it so it has the same effect.
Basically, when the host gets an input event, it redirects it to the root level controls, which will redirect them to their controls, and so on. The exception is the
OnKeyPress event which is redirected to the top level control (maybe a textbox), and the top level control redirects the event down to the parent control (or not).
It’s almost the same as for the normal Windows controls, except that there is a
FluidPaintEventArgs event. Remember that the Fluid Controls are not windows controls, and thus they don’t have their own canvas. Therefore, the controls get the
Graphics of the host control and the
FluidPaintEventArgs has a
ControlBounds rectangle that specifies where the control has to paint itself. Due to performance issues, this area is not clipped, so it would be possible to paint outside this rectangle.
Another important property of
Region. It contains the region that needs to be painted, and is the same as the region in
Graphics.Clip. So, why would I add a separate property? Because, whenever you access the
Graphics.Clip, it actually creates a copy of the
Region. So, for example, the
ListBox would create various regions whenever it checks if an
Item is within the region. This is a huge performance penalty, so I added the
Region property, which does not create a clone.
To check if a rectangle is dirty and needs to be painted, you can use the
private void PaintHeader(FluidPaintEventArgs pe)
Rectangle bounds = GetHeaderBounds();
Rectangle clip = pe.ControlBounds;
<code>ListBox derives from the
ScrollContainer class which is a base class for all controls that support touch screen scrolling.
It will allow different data sources like any
IList or a
DataTable, but currently, only
IBindingList are supported. The advantage of
IBindingList is that the
ListBox gets informed whenever something has happened to the
List, like adding or removing an item, or even modifying an item (if the developer doesn’t forget to notify the binding list by calling
List itself can contain any kind of class, simple strings, integers, or complex classes.
To display an item in the
Templates are used. A
Template is a simple panel with an additional
ItemIndex property. It is possible to use different
Templates for different classes. Therefore, you can specify either a
BindTemplate event or override the
OnBindTemplate method. In the first case, you get a
TemplateEventArgs with the item for which to obtain a template, and you can specify the template for it on the
TemplateEventArgs template property. In the latter case, the
OnBindTemplate expects to return the template that it can use, with the index and the item as well as the default
Template as parameters.
If you don’t use different
Templates, you just need to specify a default
Template property for the
ListBox. This is how I did it in Password Safe.
How does a template get the data?
It doesn’t work automatically, and you have to program this manually. There are two ways to implement this. The first way that I’m using is to override the
OnBindValue and or
OnItemUpdate methods of a derived
protected override void OnBindValue(object value)
PWNameValue item = value as PWNameValue;
if (item != null)
nameLabel.Text = item.Title;
valueTb.Text = item.Value;
nameLabel.Text = "";
valueTb.Text = "";
This method occurs as soon as a the
Item value of the
Template changes. Note the word changes!
The other method,
OnItemUpdate, however, occurs every time the
Template is prepared for usage, not only when the
protected override void OnItemUpdate(object value)
DetailListBox lb = DetailListBox;
bool isSelected = lb.SelectedItemIndex == this.ItemIndex;
nameLabel.ForeColor = isSelected ? Theme.Current.ListSecondarySelectedForeColor :
valueTb.AllowEdit = Editable && (SelectedItemIndex == ItemIndex);
This can become handy when you need to modify some properties of your template depending on the current state of the list box item itself, as the above snippet from the source code shows.
The other way to assign the data is to use the
DataBound event handler of the
public event EventHandler<TemplateEventArgs> DataBound;
or, you override the
OnDataBound method of a derived listbox. In the source code, I do not use this possibility.
Finally, if you don’t want to use any template, you can directly paint each item, by adding a
PaintGroupHeader event handler to the
ListBox, or override the
OnPaintItem method of a derived
I am using this possibility to paint a custom background for a template:
protected override void OnPaintItem(ListBoxItemPaintEventArgs e)
e.BackColor = theme.ListSelectedBackColor;
e.ForeColor = theme.ListSelectedForeColor;
e.BackColor = theme.ListBackColor;
e.ForeColor = theme.ListForeColor;
if (e.Item is GroupHeader)
e.BackColor = theme.ListHeaderBackColor;
e.Handled = true;
else if (e.IsSelected)
e.BorderColor = e.BorderColor;
e.BackColor = Color.Transparent;
e.Handled = true;
Now, you have a
ListBox that can show any kind of data.
Additionally, there are some interfaces that the
ListBox recognizes for an
Allows you to specify a distinct height for an item.
Specifies a group header which separates items, e.g., by alphabet, like it does for the passwords (see pictures).
Specifies a group header that also specifies in what background color the header should be painted, other than the predefined color.
The simplest ways to add a group header to the list is to add a
GroupHeader class with a title to the list:
private NotifyList AddHeaders(NotifyList passwords)
NotifyList list = new NotifyList();
string current = "";
foreach (PasswordData d in passwords)
string c = d.Name.Substring(0, 1).ToUpper();
if (current != c)
current = c;
list.ModifyChanged += new EventHandler(ListModifyChanged);
DataSource for a
ListBox is usually a
BindingList<object> list. Why not a more specific class like
BindingList<MyData>? Because, then you would not be able to add a group header. But, of course, you could create a
MyData class and a derived
MyGroupHeaderData class, then you would be able to specify a
BindingList<MyData> and add some group headers.
As soon as a
IGroupHeader is attached as the first item, the
ListBox adds a header that is permanently visible and shows the last available group header. It also performs an overlapping as soon as a new group header is close to be the new header. It’s hard to explain, the best is to just try it out.
The ListBox show a scrollbar on demand, as soon as the
TopOffset changes and disappears automatically after a delay.
It’s possible to use a fade effect for the disappearance of the scrollbar, and you can make the header transparent. But, I don’t use this since alpha-blending slows down the system. I will improve this by using DirectX 2D for alpha-blending functionalities instead of using methods from the GDI+ DLL.
Panel is a host for different controls, of course. Each control has a
Anchor property which specifies how to layout the control within a
Panel. There is currently no
Docking property available. It does this by directly overriding the
OnSizeChanged event of a control, but maybe, I’ll add it in a later version. The layout of the controls is smart, so the need to paint areas that are hidden by later controls is reduced, unless they are transparent.
Panel also has the possibility to act like a window. Therefore, it has the
Close methods available. As soon as you call
Show, it appears in front of the previous controls with the specified bounds. If you call
ShowMaximized, it’ll be maximized to full screen. More interesting thing is to add a
ShowTransition parameter to the Show or
ShowMaximized call. This parameter specifies that the panel should not just appear, but appear animated into the screen. There are various transitions possible, but currently, only
FromTop are supported. The fade effect is simply too slow without DirectX 2D. And, I did not need to use
FromRight. I will also add some other effects, like page turning, zooming, etc., as soon as I have the time.
void newCategoryButton_Click(object sender, EventArgs e)
CategoriesPanel cp = CategoriesPanel.Instance;
To speed up your panel, you should set
true. This creates a separate bitmap and region to invalidate, and so the canvas is only repainted when its own region has become invalidated.
EnableDoubleBuffer is smart, and does not always actually use a double buffer. It would make no sense to double buffer when it contains only one control that is already double buffered. On the contrary, it would cause a performance penalty to shift an image from one bitmap to another. The panel checks the situation, and only if it is adequate, will it create a double buffer.
Additionally, you can specify an
Alpha value lower than 255, and the panel becomes transparent if you also use
EnableDoubleBuffer. But note that alpha-blending is currently slow, and the bigger the panel is, the slower it will become.
ButtonGroup groups more buttons together. You can specify which corners of the
ButtonGroup should be rounded.
Header is, like the name says, a header control, which contains a text, a
Backbutton on the left, and a
ButtonGroup on the right.
Panel can contain multiple
Controls, but only one control is displayed at once. You can use the
Item property to change the
Control to be displayed. The interesting thing is that the
TransitionPanel uses a transition to flip from one control to another.
This is a combination of a
Header and a
TransitionPanel, which syncs the transition of the panel with the header. It also manages the
BackButton automatically, and principally, it is being used to show hierarchical structures.
Back navigates back to the previous
Forward to the next level
This is a panel that is used for a navigation panel, and has additional properties to be maintained by the
BackButton specifies a different back button, if not to be maintained by the NavigationPanel.
Buttons contains the buttons to be displayed in the header as soon as the page becomes active.
Note that I intended to also add a fading animation between the old and new buttons as soon as a page flips, but there is the same performance problem with alpha-blending as mentioned before, so let’s look at what DirectX can do…
This is a compound panel that builds, like the name says, a numeric pad for different purposes.
A predefined panel that has a text and two or less buttons at the bottom. Its purpose is to show simple dialogs with requests of two choices. You can use the
MessageDialog.Show() method to quickly show the dialog. You can also open the dialog modal, so that a transparent empty panel is above the remaining screen and lets the other controls appear darker and not touchable. In that case, you must specify an event handler to decide what to do when one of these buttons is pressed. Here comes an example:
void delPasswordButton_Click(object sender, EventArgs e)
passwordToRemove = passwordsListBox.SelectedPassword;
if (passwordToRemove != null)
MessageDialog dialog = new MessageDialog();
dialog.Message = "Delete Password?";
dialog.Result += new EventHandler<Fluid.Classes.DialogEventArgs>(dialog_Result);
void dialog_Result(object sender, Fluid.Classes.DialogEventArgs e)
Finally, I shortly mention the
controls which are primary controls.
Notice, that I mostly reuse controls, even
EventArgs. That’s because some delays appeared while I was playi… testing the scroll behavior. I figured out that the cause was the garbage collector. So for better performance, I created them either generally or first on demand.
private void EnsurePaintEvents()
if (paintEvents == null) paintEvents = new FluidPaintEventArgs();
This is the class that provides neat animations and is similar to Silverlight, though not that flexible. You have three kinds of animations:
Deceleration does what the name says. If you specify a positive
Acceleration property, the animation accelerates; with a negative value, it decelerates. The
Log (arithmic) animation is logarithmic, and is best for visual effects that look like you are releasing a rubber band. You can see that kind of animation when you move the top position of a listbox down and release your finger, and then it jumps back to the default position.
GDI+ in the .NET Compact Framework
Unfortunately, some rendering methods that I need to paint my controls are missing in the Compact Framework, though the GDI+ DLL is part of Windows Mobile. Therefore, I use a custom
GraphicsPlus class, with
Graphics as parameter, that builds a wrapper to the now available methods, like drawing shapes etc. Not everything that the Windows Mobile GDI+ offers is truly possible. Sometimes, you get a
NotImplemented exception, for instance, when you try to use a
Region with a
GraphicsPath. This does not work, so I had to do a workaround to create the glossy buttons, by creating actually two parts of a path, one for the top and one for the bottom, both with different gradients.
As the fluid controls are not window controls, there is no visual designer available. But since the target is Windows Mobile, you wouldn't create too sophistic UIs, and so the code to define the controls is not that complicated.
Something to mention about Password Safe itself.
It is designed to run on systems with a resolution of 480x800 pixels, but also works on smaller resolutions with 240x320 pixels, though some text might not be readable as the font is too small. Only the search panel that filters out passwords will not show up.
At the Category list, there is an edit button and an add (+) button on the header. When you press the edit button, a round button appears animated on each item on the left to provide an option to delete the item. As soon as you press this button, another button appears on the right to confirm the deletion. This looks nice, but is actually not very performant. The (+) button does the same, both adding and removing items. The iPhone like behavior is just a proof of concept that it is not very difficult to implement, and will be removed in later versions.
The passwords are saved in XML format which is encrypted using the top secure AES encryption.
The .NET Framework offers a lot of different symmetric and asymmetric encryption algorithms, do does the Compact Framework for Windows Mobile. But, one important class is missing in the Compact Framework:
This class provides functionality to create key data from an arbitrary password string, which is required for every encryption algorithm. You cannot simply convert the password string to a
byte array using, e.g.,
Encoding.Default.ToArray(password), since the key must be of a specific size. The size can vary by different blocks, and it depends on the algorithm you are using. For instance, the preferred AES or Rijndael algorithm requires a key size of 128, 256, 384, etc., but nothing in between. Therefore, you need an algorithm that encodes any string to a byte array of at least 128 bytes and not less or more.
Fortunately, this is what hashing algorithms do! So, as a replacement for the missing
Rfc2898DeriveBytes, we can use a hash algorithm that belongs to the Compact Framework, and that creates a size that matches the requirements for the encryption algorithm. In this case, since we are using AES, we need a hash with a size of 128 or 256, and the qualified match is the MD5 algorithm. It is not the strongest though, and SH256 would be the better choice, but unfortunately, the Compact Framework does not include this hash algorithm, so we need to use MD5.
Here comes an example of how to implement encryption/decryption for Windows Mobile.
So, after almost 7000 lines of code, I present you my Christmas vacation project. As soon as I make a final decision for the final name of the controls, I will push them to CodePlex to keep you up to date on newer versions.
I hope you like my application, and of course, I would like to participate in the Microsoft Mobile Developer Contest 2008 :-)