Showing posts with label windowsphone. Show all posts
Showing posts with label windowsphone. Show all posts

Friday, March 9, 2012

Windows Phone form validation

I've spent a lot more time than I had expected these last two days trying to figure out the best way to do form validation on Windows Phone. In the app that I'm working on there is a registration flow and at one point the user needs to provide a user name, password and some other information. All of this data need to be validated before sent to the server and if something is missing or incorrect (invalid e-mail address or a password and password confirmation isn't matching) I need to present this to the user.

On Android I would do something like:

  1. Listen to the Register button click or if I want early validation listen to text or focus change (TextWatcher or OnFocusChangeListener) on the fields in question
  2. Validate the input
  3. Call setError(string) on the invalid fields. Doing this: "Sets the right-hand compound drawable of the TextView to the "error" icon and sets an error message that will be displayed in a popup when the TextView has focus. The icon and error message will be reset to null when any key events cause changes to the TextView's text"
This will result in something like this:


Three simple steps and you get everything you need. Easy. Now how is something like this done on Windows Phone? It turns out that there's quite a few more steps involved and many pitfalls on the way...

Windows Phone does support data validation when working with data bindings and the system is pretty powerful, but in my opinion lacking in a key area, namely a way to present validation errors in a standardized way like on Android. So, how does the data validation work? If you look at the documentation referenced by Microsoft's own Eric Fleck you'll see that there's simple data validation in two-way data bindings and additional support using IDataErrorInfo and INotifyDataErrorInfo. There's also an example of how the user feedback might look like:

That looks fine and dandy and just what I needed. My first attempt at achieving this was to use simple data validation by raising an exception in the data bound setter and specifying in my XAML that the field will validate on exceptions:



And in my setter in the ViewModel:


private string _UserName;
public string UserName
{
set
{
if(IsInvalidEmail(value)
{
throw new Exception("You must enter a valid e-mail address");
}
_UserName = value;
}
get
{
return _UserName;
}
}


This looks like a very nice way of handling form validation and it doesn't really require a lot of work, but the problem is that I did not get the nice little tooltip when I entered an incorrect e-mail address. My first thought was of course that there was something wrong with my binding or that the exception wasn't handled properly. I did however manage to verify that the validation was working by providing an event listener via the BindingValidationError property. If you add an event listener and make sure you have NotifyOnValidationErrors=True you'll trigger the event each time you come across a validation error. 


As a side note: It took me a while to figure out how to add a data binding to the BindingValidationError property (I'm trying to be a good MVVM boy here and leave my code behind as clean as possible) since you cannot bind to events out of the box. You need to use BindEventToCommand from MVVM Light to get this working.

Ok, back to my missing tooltip. I did a great deal of Googling and read numerous blog posts about data validation where examples of data validation with tooltip feedback was used, but the more I read the more unsure I became if this really was supported on Windows Phone and not only present in Silverlight on the web. I finally came across indication that this was the case. Eric Fleck (again) posted (although admittedly one year before the post mentioned above) that "the standard control templates do not act upon the ValidationStates and this is why nothing appears to happen when you set ValidatesOnException to true". Eric continues by saying that "you can override a control template to add ValidationStates", but at this point I'm losing hope of an easy solution using ValidatesOnException and I abandon the whole thing and look at an alternative.

What I end up doing is that I add validation feedback as textblocks below each textbox and by default set their visibility to collapsed (i.e. not visible). I then databind the visibility of the feedback texts to properties such as IsInvalidUserName, IsPasswordsNotMatching and so on in my view model and use a data binding converter to convert from booleans to Visibility (Visible and Collapsed).

One of my biggest take-aways from all of this is that the Windows Phone documentation is lacking in some key areas and that it many times is extremely hard for a new Windows Phone developer to actually know if documentation and examples are valid for WP and not only for Silverlight on the web. The Windows Phone development quickstarts are good and very clear, but they often don't go into enough detail and this is the times when I've found myself in the wrong place reading the wrong documentation.

A final remark: Does tooltips actually work on windows phone? You can set  ToolTipService.ToolTip="Some text" and  ToolTipService.Placement="Right" on any control in your XAML, but I have so far never been able to display one.

Tuesday, March 6, 2012

Windows Phone - Are they mad?

Today I came across my first real Windows Phone WTF moment. I needed to show a long text and that should be a very trivial matter on almost any platform. Is it non-trivial on Windows Phone? No.

Imagine this: No controls (buttons, images, textboxes etc) can have a width or height larger than 2048 pixels. This has to do with the hardware rendering and texture sizes in some way and it completely prevents you from displaying a long text (such as the very verbose "Terms & Conditions" text I needed to show)... how on earth can such a limitation exist on a modern device and platform such as Windows Phone?

So what's the workaround? Well, from what I figured the best way is to split the text into several texts, each less than 2000 pixels high. Luckily there's a class that Alex Yakhin has made available on an MSDN blog. The class comes packaged into a DLL which means that you can't really modify it that much. Another option would be to display the text in a web control, but that is cumbersome if it's local data from a text resource (you need to write it to a file in IsolatedFileStorage first).

In my case neither of the solutions work well. I wanted a page with a title, a long text and a button below the text and all of the page should scroll. Using Alex Yahkin's class the title would not move and neither would the button. The same goes for the web control...

Windows Phone - Bing Maps and Location tracking

Yesterday I set up a quick test of Bing Maps and location tracking (using GPS and/or network)  for Windows Phone. Location tracking is very similar to how it's done on Android:

  1. Get an API key ( http://www.bing.com/toolbox/bingdeveloper/)
  2. Create a GeoWatcher instance (Android equivalent: LocationManager)
  3. Add event listeners for when the position or location status has changed
  4. Start the GeoWatcher instance in it's own thread (Android equivalent:  LocationManager.requestLocationUpdates which does step #3 and #4 in one go)
  5. Receive location updates as GeoCoordinates containing latitude, longitude and optionally altitude, accuracy, speed and course. Latitude and longitude are in the range -180.0 to 180.0 as opposed to the Android micro degrees
And when it comes to the actual map it's not really any different from working with Google Maps either:

  1. Add a Map tag to your XAML and your API key as an attribute
  2. Add optional things like starting zoom level and if zoom controls should be visible or not
  3. As child tags you can add PushPins, Layers and Shapes (to plot routes and areas)
The above can be done programatically of course. I did however decide to go for full use of XAML and databinding to bind the "I'm here" pushpin location to the location I get from the GeoWatcher. Simple and very elegant.

Wednesday, February 29, 2012

Windows Phone - Google Analytics tracking

Yesterday I had a look at the options available to Windows Phone developers wanting to add Google Analytics tracking to their Windows Phone apps. I had expected this to be a bit tricky since Microsoft and Google aren't best friends neither of them wish to promote the other's products. I was right.

There's something called Microsoft Silverlight Analytics Framework with support for a whole bunch of different analytics services and this seems to be the recommended framework if you want to track user behavior in WP apps. Unfortunately this doesn't come as a NuGet package so you need to download and install a separate MSI. I'm aware of the fact that the NuGet package manager isn't an official Microsoft product, but it really does simplify the process of installing third-party libraries.

Since I'm doing this with my Android hat on I was expecting something at least remotely similar in setup time to EasyTracker. I was wrong. Not only does it require me to write an AnalyticsService and AnalyticsTracker class and add the service to the App.xml, I also need to make sure to add the right dlls to my project (NuGet would have done this for me). Among the required dlls there's one called System.ComponentModel.Composition.dll and you would expect to find that one in the component called ComponentModel, but no, if you add that one you'll get a runtime error related to a class called CompositionHost. What you need to do is to make sure to add the Microsoft.SilverlightMediaFramework.Compatibility.Phone dll, because that's the dll that contains the correct version of the CompositionHost...

I finally figured it out and now I have the whole thing set up complete with dependency injection and all:

public class MyClass
 [Inject]
 public IAnalyticsTracker AnalyticsTracker { get; set; }

        public void SomeFunction()
        {
   AnalyticsTracker.TrackEvent("MyCategory", "MyName");

Note: Page tracking can be handled automatically by the framework so there's no need to do this manually.

Windows Phone from an Android Developer's Perspective - The first week

I recently got assigned to take a look at Windows Phone development for an upcoming project at work. I regret that I didn't start blogging about this from day one since it would have been an interesting account of how it is to come as an Android developer to the Windows Phone platform. Anyway, here's a quick summary of the first week with WP:

Language
My first reaction to Windows Phone and C# was actually a lot more positive than I had anticipated it would be. The C# syntax is not at all weird (unless you start messing with lambda expressions). It feels like a mix between Java and ActionScript, both of which I'm very comfortable.

Android vs Windows Phone
1-1
IDE
The standard Visual Studio Express IDE was a disappointment with a lot of features lacking compared to Eclipse. I'm aware of the fact that a lot of the shortcomings will go away once I get Visual Studio Professional and ReSharper, but that comes at a price of almost €800...


Android vs Windows Phone
2-1
User Interface
Another positive experience was the way Windows Phone user interfaces are created. Windows Phone UIs can be created using XAML files where components are arranged in nested tags just like on Android. Each XAML has what is called a code-behind C# file that initializes the view by parsing the XAML. From the code-behind C# file you get immediate access to the components on the view (you don't even have to do findViewById). And to add a big cherry on top you also have the possibility to add data bindings between the XAML and an underlying data context.

This way of defining the UI and the ability to use data bindings has led to the de-facto Windows Phone standard of separating view and logic into a pattern called MVVM (Mode View ViewModel). The idea is that the View (XAML + code-behind) is wired to a ViewModel using databindings and the ViewModel is the one responsible for providing the view with data to show from the model. This means that you'll have a ViewModel without any references to UI components and UI code, thus making it testable.

I wouldn't say that the Windows Phone way of defining and working with views and UI components is better than Android, but it sure has it's advantages. On the other hand does Android handle styling better (by a small margin though) and Android has some very nice features for working with shape drawables that I haven't seen on Windows Phone.

Android vs Windows Phone
3-2
Logging
Logging on Windows Phone is done using Debug.WriteLine() calls, similar to the Log.d() call on Android. If you want anything more fancy and wrap this into a framework with the ability to send logs to different targets, set log level filtering and things like that you probably go for SLF4J on Android. When you want to do the same on Windows Phone there's a few frameworks to chose from and the one I tested the most was NLog.

Unfortunately NLog wasn't as painless to work with as SLF4J. NLog has a lot of targets to chose from out of the box, but not one for the Debug.WriteLine. NLog can log to the console, but that only works on the emulator (and only after a registry hack). I tried to use one of the network targets to send logs to a separate log reader (for instance Apache Chainsaw) but it proved damn near impossible to get it to work. I ended up scrapping NLog and instead wrote my own wrapper for Debug.WriteLine with log levels and parameterized log messages (i.e. logger.debug("some output p1: {} p2: {} p3: {}", "param1", 2, parameterThreeObject)

Android vs Windows Phone
4-2
JSON
Json parsing on Windows Phone is as painless as on Android. On Android you either chose Gson or Jackson and similar functionality on Windows Phone is provided by Json.NET. There's also native Json parsing, but Json.NET is more feature-complete than the native functions.

Android vs Windows Phone
5-3

REST
Making network calls on Windows Phone is a really painless business. There's a simple WebClient with methods for doing asynchronous calls to not hang the UI and there is the more advanced HttpWebRequest. So far it seems like there's little need to use anything other than the WebClient. I did however also have a look at a framework called RestSharp and it handles automatic deserialization of XML and JSON (using Json.NET), supports GET, POST, PUT, DELETE, handles authentication and file uploads.


Android vs Windows Phone
5-4

Dependency Injection
I've come to fall in love with the concept of dependency injection/inversion of control and I've become really familiar with the way it's done on Android using Guice/RoboGuice. One of the first things I did when I started with Windows Phone was to try and find a Guice equivalent. The product that in my opinion best fills the role on Windows Phone is Ninject. Ninject supports several different ways of setting up the bindings, it has several different injection patterns, it supports providers and everything else you can do with Guice.



Android vs Windows Phone
6-5

Persistence
I have not had a chance to explore this enough yet, but I did try the IsolatedStorageSettings which is a persistent key-value pair map available only to your own app. It works in a similar way to the SharedPreferences on Android, but it handles any kind of values, even complex objects can be persisted. I haven't had a chance to try the file and database APIs yet, so I can't really judge those.


Android vs Windows Phone
6-5

Testing on a device
This was a real disappointment, but not really a surprise. I have gotten so used to the openness of the Android platform that I came to expect that I would be able to test my code straight away on the Nokia Lumia 800 phone we bought. Alas, you need a Live-ID (not a big deal), an AppHub account, a Zune installation and you need to unlock your phone for developer testing. Getting a Live-ID is not so different from signing up for a Google Account, it is what identifies you across the somewhat sprawling set of Microsoft products. Getting an AppHub account is a matter of signing up for an annual $99 subscription and if you are registering as a company waiting a few days until GeoTrust has verified your account. GeoTrust, seriously? Why on earth is this required at all and why is this process handed over to a third party? Zune is unfortunately unavoidable and it seems like unnecessary software for me as a developer to have to install on my machine.


Android vs Windows Phone
7-5


Summary
Working with Windows Phone was not at all as bad as I had expected it to be. I have been positively surprised by a lot of the things I've seen so far and I do hope that my initial positive experience will stick when I really get my hands dirty in the weeks to come.