30 September, 2010

WP7: Consistent error handling and how to display errors on a Windows Phone

As the UI of a phone is somewhat different than a traditional “interface” (i.e. a PC); you have to apply different approaches when it comes to displaying errors to the user.

In the “normal world” – e.g. a web application has a common error page that you lead your users to when something unfortunate happens. This is setup in web.config as a dedicated page for errors. On the Windows Phone, you can re-use that concept and have a common error page. Not that it is setup in app.config; but it is a common page you use for displaying “human readable” error messages to the user. The concept is seen here:

image

When an unhandled exception has happened; this is caught in the App (Application) and the Application is redirected to the error page (ErrorView). The below is taken from App.xaml.cs and presents the Application_UnhandledException method. This is by default hooked up in the constructor of the App-class.

// Code to execute on Unhandled Exceptions
private void Application_UnhandledException(object sender, ApplicationUnhandledExceptionEventArgs e)
{
if (System.Diagnostics.Debugger.IsAttached)
{
// An unhandled exception has occurred; break into the debugger
System.Diagnostics.Debugger.Break();
}

//is handled by this method.
e.Handled = true;

//route to error view
Dictionary<string,string> data = new Dictionary<string,string>();
data.Add(Constants.ERROR_NAME, e.ExceptionObject.Message);

ApplicationController.Default.NavigateTo(ViewType.Error, data);
}

As seen, then an unhandled exception is caught in the App class, the Exception is set to Handled = true and the ApplicationController is used for navigating to the ErrorView. This will then be presented to the User as a common error page. What happens next, is the responsibility of the developer and your application context ;-)


image


 

Technorati Tags:

25 September, 2010

WP7: my localization is not working?

If you ever find yourself attempting to make the localization work in WP7 (and it doesn’t!); you properly forgotten the below little “issue”.

When you add new supported languages to your application like this
- ApplicationTexts.resx
- ApplicationTexts.de-DE.resx
- etc…

and you find that (in this case) the German language are not kicking in when you change display language on the phone, you most likely forgot to change the access modifier. Default is internal – change this to public and you are all set to go!

image

Technorati Tags: ,

22 September, 2010

WP7: NavigationService support when using MVVM

Update (30.03.2011): See this post for a MVVM-framework with built-in support for navigation based on the below: http://blog.clauskonrad.net/2011/03/simplemvvmtoolkit-in-improved-version.html

The MVVM pattern has an inherent problem when it comes to navigation. Should the ViewModel (VM) be responsible for navigation to and from the neighboring Views (and thereby know about them!) or should we have a dedicated class responsible for this navigation? With Separation of Concern (SoC) in mind; I would advocate for using a dedicated ApplicationController to navigate between the different Views in the application.

As an example; let’s pretend that a User clicks a button in say View1 to navigate to View2; should the View1 know where the View2 exists? Or even that it exists? I don’t see that it is a problem for the Views to know what neighboring views that might exist in an application ? This is where the ApplicationController comes into play. This dedicated class has the single responsibility of knowing all views and where they reside in this context.

View
Responsible for how to display data (rendering of UI). Does not know anything about the ViewModel.

ViewModel
Responsible for what data to display (interacts with the business layer for data). Does not know anything about the Views.

ApplicationController
Absolutely part of the UI-layer, but knows how to navigate between the different Views. This controller knows the whereabouts of the different Views in the Application.

As seen from the below figure – a single ViewModels exists for each View (1:1). These VM’s delegates the task of navigating from say View1 –> View2 to the ApplicationController and thereby leaves responsibility to this controller.

image

Conceptual view of architecture.

That’s all grand – so where is the problem here?
The problem lies in the way Silverlight and MVVM works together. The NavigationService is only known to the View as it is a property of PhoneApplicationPage from which the Views inherit, and the ViewModel has no concept of this NavigationService (the ViewModels are just plain clr-classes). Due to this reason, the ViewModel nor the ApplicationController can perform navigation on it’s own. We need some way of informing the ApplicationController of the NavigationService provided by the Views. How to do this in a neat way?

This is the ApplicationController implementation. As seen in the NavigateTo method, the ApplicationController takes out the NavigationService from the Application.Current.RootVisual class. It now has access to the NavigationService and can call .Navigate on this service.

public enum ViewType{Home, Session, Statistics}

public class ApplicationController
{
static ApplicationController m_instance;
Dictionary<ViewType, Uri> m_Views;

ApplicationController()
{
m_Views = new Dictionary<ViewType, Uri>();

//register views with controller
Register(ViewType.Home, new Uri("/", UriKind.Relative));
Register(ViewType.Session, new Uri("/ExerciseView.xaml", UriKind.Relative));
Register(ViewType.Statistics, new Uri("/StatisticsView.xaml", UriKind.Relative));
}

public static ApplicationController Default
{
get
{
if(m_instance == null)
m_instance = new ApplicationController();

return m_instance;
}
}

void Register(ViewType type, Uri address)
{
if (m_Views.ContainsKey(type)) //update
{
m_Views[type] = address;
return;
}

m_Views.Add(type, address); //add
}

void UnRegister(ViewType type)
{
if (m_Views.ContainsKey(type))
m_Views.Remove(type);
}

public void NavigateTo(ViewType type)
{
if(!m_Views.ContainsKey(type))
return;

Uri address = m_Views[type];

//magic code here!
PhoneApplicationFrame root = Application.Current.RootVisual as PhoneApplicationFrame;
Debug.Assert(root != null, "Root is null");
root.Navigate(address);
}



The ViewModels interact with the ApplicationController in this way:

public class MainViewModel : ViewModelBase
{

/// <summary>
///
Initializes a new instance of the MainViewModel class.
/// </summary>
public MainViewModel()
{
if (IsInDesignMode)
{
// Code runs in Blend --> create design time data.
}
else
{
//bind Command to action
NavigateToNewSession = new RelayCommand(() => SendNavigateToSessionCmd());
NavigateToStatistics = new RelayCommand(() => SendNavigateToStatCmd());
}
}


public string ApplicationTitle
{
get
{
return Constants.APPNAME;
}
}

public string PageName
{
get
{
return "Welcome";
}
}

public ICommand NavigateToNewSession { get; set; }

void SendNavigateToSessionCmd()
{
//move to session page
ApplicationController.Default.NavigateTo(ViewType.Session);
}

public ICommand NavigateToStatistics { get; set; }

void SendNavigateToStatCmd()
{
//move to statpage
ApplicationController.Default.NavigateTo(ViewType.Statistics);
}
}



And finally the XAML from the View binding the View to the ViewModel is seen here:

            <Button Content="Start" Height="72" HorizontalAlignment="Left" Margin="100,156,0,0" VerticalAlignment="Top" Width="255" >
<
Custom:Interaction.Triggers>
<
Custom:EventTrigger EventName="Click">
<
GalaSoft_MvvmLight_Command:EventToCommand Command="{Binding NavigateToNewSession}"/>
</
Custom:EventTrigger>
</
Custom:Interaction.Triggers>
</
Button>



Note: See this post for how to make ICommand support in SL3 and WP7: http://blog.clauskonrad.net/2010/09/wp7-and-missing-icommand-support-on.html


As seen from the above – the View is bound to the ViewModel’s ICommand property (called ‘NavigateToNewSession’). Now the ViewModel is invoked when ever the Button is clicked and the ViewModel asks the ApplicationController to move to another View (where ever that might reside!).


To put it in another way: nobody knows anything about anything ;-), but only knows about what they need to do. This is really SoC in a nutshell: “I’m only interesting in knowing that I need, to be able to fulfill my job in the world”.

Clean and (not so) simple!



WP7 and (missing) ICommand support on buttons

Update (30.03.2011): This workaround is available too in the SimpleMVVMToolKit. See this posting on how to accomplish this using SimpleMvvmToolKit. http://blog.clauskonrad.net/2011/03/wp7-hello-world-using-simplemvvmtoolkit.html

As WP7 is based on SL3, no out-of-the-box ICommand support is provided. This is quite inconvenient if you attempt to implement an application built on the MVVM pattern. If you however uses the MVVM Light framework from Galasoft, it becomes quite easy to implement! The big problem with this framework however, is that it is extremely hard to find a decent example on how to do this. So here goes:

image  

I’m trying to make the “Goto Page 2” button support ICommand and bind it to a ViewModel.

1) Add the button to the XAML-file in Visual Studio
2) Open the file in Expression Blend (see below)

image
3) Drag/Drop the Behaviour “EventToCommand” (GalaSoft) to the button. This will add this to your XAML-file:

 <Button Content="Goto Page 2" Height="72" HorizontalAlignment="Left" Margin="117,454,0,0" VerticalAlignment="Top" Width="232">
<
Custom:Interaction.Triggers>
<
Custom:EventTrigger EventName="Click">
<
GalaSoft_MvvmLight_Command:EventToCommand Command="{Binding Navigate}"/>
</
Custom:EventTrigger>
</
Custom:Interaction.Triggers>
</
Button>


Note the <Custom:Interaction.Triggers> tag added. This attached property of the Button allows for Command binding. The binding {Binding Navigate} binds to this ViewModel:

image 


So here you have the ICommand support added to a SL3 button.



Technorati Tags: ,,

17 September, 2010

WP7 installation experience

Installed the final WM7 tool bits yesterday. It took a really long time (read: 4-5 hours!). Alas it did not even work when done ;-(

The only way to make it work in my development machine which is loaded with pre-release, beta and other “versions” of software; was to download the standalone ISO file and install locally. This in contrast worked like a charm.

The ISO-file (image) can be downloaded here: http://go.microsoft.com/fwlink/?LinkId=201927

16 September, 2010

WP7 tools are final + installation

So – finally they finished them!
VS2010 tooling is found here: http://go.microsoft.com/fwlink/?LinkId=185584.

From Scott G’s blog:
The Windows Phone 7 Toolkit includes the following additional Silverlight controls and components that are customized for the Windows Phone 7 experience:

  • ContextMenu
  • DatePicker
  • TimePicker
  • WrapPanel
  • ToggleSwitch
  • GestureService – adds events for Tap, DoubleTap, Hold, Drag (DragStarted, DragDelta, DragCompleted), Flick and Pinch

Especially the GestureService looks very promising!

Update: The install takes REALLY long time! Be prepared.

14 September, 2010

Expression Blend: how to integrate into TFS

To my great surprise, it turns out that Expression Blend 3/4 indeed does have support for Source Control Systems (like TFS)!

image

This is basically set up automatically, if you open a project that has already been bound. Otherwise it is not possible.

How to do:
1) Create the project in VS 2010
2) Bind the project to TFS (“Add Solution to Source Control…”)
3) Check In and Close the project
4) Open the same project (use the solution file (.sln file)) from inside Expression Blend
5) Done – you have integrated support for ‘get latest’ etc. in Expression Blend

Technorati Tags: ,

WP7: Support for local databases?

Coming from pre-WM7 systems, I’m quite used to having support for some breed of SQL Server (SQL CE) on devices. Well – it is not supported (in V1) on WM7. A number of alternatives exists here:

1) Sterling http://sterling.codeplex.com/
A Isolated Storage located database functionality.
Sterling is a lightweight object-oriented database implementation for Silverlight and Windows Phone 7 that works with your existing class structures. Sterling supports full LINQ to Object queries over keys and indexes for fast retrieval of information from large data sets.

2) PERST (Object database)
See Andy Wigley’s blog for additional info http://mobileworld.appamundi.com/blogs/andywigley/archive/2010/06/07/perst-a-database-for-windows-phone-7-silverlight.aspx

Haven’t tried them out at this time, but as time permits – I surely will!

Update: See this post: http://blog.clauskonrad.net/2010/10/how-to-database-for-wp7.html

Technorati Tags:

WP7: How to make a phone call from your own application

How difficult can it be? Well – in the coming WP7 platform; making a phonecall from your own application is so easy that you won’t believe it!

image image image

WP7 introduces a new concept called Launchers. A Launcher is an object that basically tombstones your application and instead launches/activates a system functionality (in this case the Phone service). The code that does the above is here (is is darn easy!):

void btnLaunchPhone_Click(object sender, RoutedEventArgs e)
{
var pt = new PhoneCallTask();
pt.DisplayName = "Claus Konrad";
pt.PhoneNumber = "+45111111";

pt.Show();
}

Technorati Tags:

09 September, 2010

WPF ListView, MVVM and (missing) ICommand support

As great an experience WPF can be in conjunction with the MVVM pattern, as poor an experience it can be to learn that the standard WPF ListView does not support the ICommand pattern that is used otherwise in MVVM implementations. And this in particular to the ListView.SelectionChanged event which is very commonly in use!
Of course you can handle this by subscribing directly to the SelectionChanged event and code your way inside the View (UI), but that kind of contradicts the purpose of the MVVM pattern in the first place. The View should know absolutely nothing about code nor should it know anything about the ViewModel. All interaction from the View’s point of view should be handled by the ViewModel (the “Presenter” if you will).
Well – WPF defines attached properties which allows us to make the ListView support the ICommand pattern. Here is how to declare a new class (SelectionBehavior) that caters for this.
public class SelectionBehavior{
    public static DependencyProperty SelectionChangedProperty =
       DependencyProperty.RegisterAttached("SelectionChanged",
       typeof(ICommand),
       typeof(SelectionBehavior),
       new UIPropertyMetadata(SelectionBehavior.SelectedItemChanged));

    public static void SetSelectionChanged(DependencyObject target, ICommand value)
    {
        target.SetValue(SelectionBehavior.SelectionChangedProperty, value);
    }
    
    static void SelectedItemChanged(DependencyObject target, DependencyPropertyChangedEventArgs e)
    {
        Selector element = target as Selector;
        if (element == null) throw new InvalidOperationException("This behavior can be attached to Selector item only.");
        if ((e.NewValue != null) && (e.OldValue == null))
        {
            element.SelectionChanged += SelectionChanged;
        }
        else if ((e.NewValue == null) && (e.OldValue != null))
        {
            element.SelectionChanged -= SelectionChanged;
        }
    }
    
    static void SelectionChanged(object sender, System.Windows.Controls.SelectionChangedEventArgs e)
    {
        UIElement element = (UIElement)sender;
        ICommand command = (ICommand)element.GetValue(SelectionBehavior.SelectionChangedProperty);
        command.Execute(((Selector)sender).SelectedValue);
    }
}


It will be used with this XAML:
<!--List of persons--><ListView ItemsSource="{Binding Persons}" 
   SelectedItem="{Binding CurrentPerson}" 
   local:SelectionBehavior.SelectionChanged="{Binding ItemSelectedCommand}">


Attached properties are in reality not properties at all. They are actually translated into method-calls by the XAML-parser when parsing the declarations found in the XAML-files. So, if you note the ‘local:SelectionBehavior.SelectionChanged’ section in the above XAML-snippet, this is where the XAML-parser will call the static SetSelectionChanged method (by convention!) on the SelectionBehavior class. This method in turn will call SelectionChanged when it is invoked.

So far so good. Now how do I bind this to an ICommand on my ViewModel, you might ask?The SelectionChanged method is linked to a local method (PresentPersonHelper)  in my ViewModel via a DelegateCommand (ItemSelectedCommand) I setup:
class ViewModel : INotifyPropertyChanged
 {
     List<Person> m_personLst;

     public ViewModel()
     {
         //default
         m_person = new Person();
       
         //wire ICommand to method 'PresentPersonHelper'
         ItemSelectedCommand = new DelegateCommand(x => PresentPersonHelper(CurrentPerson.Id));

         //load list
         var provider = new PersonProvider();
         Persons = provider.GetPersons();
     }

     public ICommand ItemSelectedCommand { get; set; }


So when ever the ItemSelectedCommand is invoked, it will delegate a call to PresentPersonHelper and do what ever that method does. Control is back inside the ViewModel where it belongs!

08 September, 2010

WP7: Styling and FontSizes

Just a quick note here.
When you find yourself sizing controls (e.g. TextBlocks) in a Windows Phone 7 (WP7) application, how do you determine what e.g. fontsize to use? Will fontsize = 24 be better than fontsize = 32? This is not as fixed as is the case with XCode, iPhones and Apple.

So what to do?
Always rely on the built-in static resources found in the framework! Never set the size explicitly in code nor in XAML! It will come back and bite you in the neck when your application is installed on a differently sized device compared to your development machine. You never know when MS will decide to change something here ;-)

An example of a textblock sized using the StyleAttribute:
<!--TitlePanel contains the name of the application and page title-->
<StackPanel x:Name="TitlePanel" Grid.Row="0" Margin="24,24,0,12">
<
TextBlock x:Name="ApplicationTitle" Text="My First Application" Style="{StaticResource PhoneTextNormalStyle}"/>
<
TextBlock x:Name="PageTitle" Text="Damage Calc" Margin="-3,-8,0,0" Style="{StaticResource PhoneTextTitle1Style}"/>
</
StackPanel>

Note the Style={StaticResource PhoneTextNormalStyle}” attribute set on the textblock. This styles the controls as the framework sees fit, and in this way you make sure that your application meets the look-and-feel of a WP7 application. And this regardless of any possible change in screen resolution (as this is handled by the framework). At this time 800 x 480 is the de-facto resolution though.

What Styles are possible then, you might be wondering?
If you enter this path: C:\Program Files\Microsoft SDKs\Windows Phone\v7.0\Design; you will see a large number of themes. Inside each theme, 2 XAML files exists. These files declares the valid names you can use, so open any ‘ThemeResources.xaml’ file and see the names.

Here is how the folder should look like with all the different themes. In addition a ‘ThemeResources.xaml"’ file is shown.
themesWM7 themesWM7_2

Technorati Tags:

WP7: How to force numeric keyboard

When you have a textbox that you wish to allow the User to enter values into; do so in an intuitive and nice way. Keyboard presses on a phone should in general be avoided as much as possible, hence when ever you are forced to display a keyboard – show the right keyboard as the first option! Your users will definitely love you for it!

On a WP7 phone, 2 keyboards are possible. The default (left) and the numeric (right):
Update: More than 2 exists! I've so far counted 8!

Default keyboard Numeric keyboard

So - how does one force the numeric keyboard? Here comes in the InputScope attribute to the rescue.

In XAML (verbose version) it looks like this:
<TextBox Height="72"HorizontalAlignment="Left"Margin="186,46,0,0"x:Name="tbxPrice"VerticalAlignment="Top"Width="244">
<
TextBox.InputScope>
<
InputScope>
<
InputScopeName NameValue="CurrencyAmount"/>
</
InputScope>
</
TextBox.InputScope>
</
TextBox>

And the non-verbose XAML version looks like this:
<TextBox Height="72" HorizontalAlignment="Left" Margin="186,46,0,0" x:Name="tbxPrice" VerticalAlignment="Top" Width="244" InputScope="CurrencyAmount"/>

It will make the Numeric keyboard pop up when ever the textbox is entered.
Details can be found here: http://msdn.microsoft.com/en-us/library/ff626520(VS.92).aspx

Another (better) info is found here: http://msdn.microsoft.com/en-us/library/system.windows.input.inputscopenamevalue%28VS.96%29.aspx

Technorati Tags:

InRiver: Not loading your extensions?

(You really need to in the loop to appreciate the issue this post addresses). Man, I've been fighting this problem for hours before I ...