Windows Phone and Mobile Services on ioProgrammo

24/10/2014 1 comment

A new article of mine has been published on n°194 of ioProgrammo (November/December 2014). This time I show how to create an agenda app for Windows Phone that uses an Azure Mobile Service with the .NET Backend.

ioProgrammo November/December 2014

ioProgrammo November/December 2014

DialogService in MVVM Light V5

14/10/2014 Leave a comment

Some days ago we talked about the new release of MVVM Light Toolkit and, in particular, we presented the new NavigationService.

The other service that is shipped with MVVM Light V5 is DialogService, that is able to show message dialogs in our apps. To use it, we simply need to register this type in the ViewModelLocator class:

public ViewModelLocator()
{
    ServiceLocator.SetLocatorProvider(() => SimpleIoc.Default);

    SimpleIoc.Default.Register<IDialogService, DialogService>();
    // Other registrations...

    SimpleIoc.Default.Register<MainViewModel>();
}

Basically, the IDialogService interface contains the ShowMessage method, with some overloads. For example:

public class MainViewModel : ViewModelBase
{
    private IDialogService dialogService;

    public RelayCommand TestDialogServiceCommand { get; set; }

    public MainViewModel(IDialogService dialogService)
    {
        this.dialogService = dialogService;

        TestDialogServiceCommand = new RelayCommand(async () =>
        {
            // Simple message without callback.
            await dialogService.ShowMessage("Simple message text", "Title");

            // Message with custom buttons and callback action.
            await dialogService.ShowMessage("Are you sure you want to continue?", 
                "Confirmation",
                buttonConfirmText: "Continue", buttonCancelText: "Discard", 
                afterHideCallback: (confirmed) =>
                {
                    if (confirmed)
                    {
                        // User has pressed the "confirm" button.
                        // ...
                    }
                    else
                    {
                        // User has pressed the "cancel" button
                        // (or has discared the dialog box).
                        // ...
                    }
                });
        });
    }
}

At line 15, we use the simplest version of ShowMessage: we just show a dialog box with a message and a title. Instead, the second example (lines 18-25) shows a message box with two buttons, Continue and Cancel; when the user taps one of them (or discard the question), the afterHideCallback action will be invoked. It will get a boolean parameter indicating if the “confirm” button (true) or the “cancel” button (false) was pressed (or if the dialog was discarded).

The IDialogService interface exposes also the ShowError method, that can be used to display information about an error (it accepts an Exception as first argument). However, we must notice that on some platforms, like Windows Store and Windows Phone, ShowError has the same output of ShowMessage (because these platforms don’t have the concept of error message box).

Categories: C#, MVVM, Windows Phone, WinRT

NavigationService in MVVM Light V5

10/10/2014 11 comments

Two days ago, at Xamarin Evolve conference in Atlanta, has been announced the availability of MVVM Light V5. This release contains interesting updates for Xamarin, as we can read in the official blog post.

Another important news is the inclusion of the INavigationService and IDialogService interfaces with corresponding implementations on supported platforms. They are objects that very often are created in each project, so now we can use the existing classes instead of creating new ones.

Let’s see how to use the INavigationService interface in our Universal Windows apps. First of all, we need to add a reference to MVVM Light V5 using NuGet:

Adding MVVM Light V5 to the project

Adding MVVM Light V5 to the project

Creating the NavigationService is straightforward. In the ViewModelLocator class we write something like this:

public ViewModelLocator()
{
    ServiceLocator.SetLocatorProvider(() => SimpleIoc.Default);

    var navigationService = this.CreateNavigationService();
    SimpleIoc.Default.Register<INavigationService>(() => navigationService);

    SimpleIoc.Default.Register<IDialogService, DialogService>();

    SimpleIoc.Default.Register<MainViewModel>();
    SimpleIoc.Default.Register<DetailsViewModel>();
}

private INavigationService CreateNavigationService()
{
    var navigationService = new NavigationService();
    navigationService.Configure("Details", typeof(DetailsPage));
    // navigationService.Configure("key1", typeof(OtherPage1));
    // navigationService.Configure("key2", typeof(OtherPage2));

    return navigationService;
}

In the CreateNavigationService method (lines 14-22), we create a new instance of the NavigationService class (that is contained in the new GalaSoft.MvvmLight.Views namespace). We need to call its Configure method to associate each page type with a key. For example, at line 17 we associate the Details key with the DetailsPage page. Then, in the class constructor, we register the INavigationService interface specifying the concrete object that must be returned when it is requested (line 6).

Now, we can define the MainViewModel as follows:

public class MainViewModel : ViewModelBase
{
    private INavigationService navigationService;

    public RelayCommand DetailsCommand { get; set; }

    public MainViewModel(INavigationService navigationService)
    {
        this.navigationService = navigationService;

        DetailsCommand = new RelayCommand(() =>
        {
            navigationService.NavigateTo("Details", "My data");
        });
    }
}

When the DetailsCommand command is executed, at line 13, we invoke the NavigateTo method on the INavigationService reference, specifying the key that corresponds to the page to navigate to (DetailsPage, in this example). We’re using simple strings to control the navigation, so ViewModels don’t need to know the Views that will be actually opened (and thus without breaking the MVVM pattern).

We’re calling an overload of the NavigateTo method that accepts an object parameter that will be passed to the OnNavigatedTo method of the requested page (in the Parameter property of NavigationEventArgs):

public sealed partial class DetailsPage : Page
{
    // ...

    protected override void OnNavigatedTo(NavigationEventArgs e)
    {
        var parameter = e.Parameter as string;  // "My data"
        base.OnNavigatedTo(e);
    }
}

Of course, as we’re following the MVVM pattern, we don’t want to use code-behind. So, the preferred approach to get navigation parameters is the one presented in the article Calling ViewModel methods in response to Page navigation events using MVVM Light in WinRT to automatically pass this parameter to the ViewModel.

Lastly, the INavigationService interface exposes also the GoBack method, that allows to return to the previous page in the navigation stack.

Categories: C#, MVVM, Windows Phone, WinRT

How to correctly use the Mobile Services SDK with MVVM in Universal Windows apps

07/10/2014 Leave a comment

If we want to use an Azure Mobile Service in our Universal apps, we can take advantage of the Add | Connected Service menu command. In this way, a static reference to a MobileServiceClient instance is added to the App.xaml.cs file.

However, if we’re following the MVVM pattern, this approach isn’t correct: we surely need to access the client from ViewModels, and so in this case we should reference the App class.

The solution is simple. Suppose we have added the MVVM Light Toolkit to the project. We can leverage the ViewModelLocator class to register an instance of the client:

SimpleIoc.Default.Register<IMobileServiceClient>(() =>
{
    var client = new MobileServiceClient(
        applicationUrl: "",
        applicationKey: "");

    return client;
});

We use an overload of the Register method that is able to create the instance that must be returned when the given type is resolved. In this case, we create the MobileServiceClient specifying the Service Url and the Application Key.

Doing so, we can pass a reference to the client to our ViewModels:

private IMobileServiceClient client;

public MainViewModel(IMobileServiceClient client)
{
    this.client = client;
    // ...
}

In this way, the MVVM pattern is respected and we can use the Mobile Service in our ViewModels as we expect to do.

ScrollToBottom Behavior for ListView in MVVM based Universal Windows apps

30/09/2014 Leave a comment

In some cases, we may need to automatically scroll the content of a ListView as items are added to it (for example, in a chat-like app). To do this, we can use the ScrollIntoView method of the control.

However, if we’re following the MVVM pattern, this approach ins’t correct. We should instead use a Behavior that automatically scrolls the content when a new item is added:

public class ScrollToBottomBehavior : DependencyObject, IBehavior
{
    public DependencyObject AssociatedObject { get; private set; }

    public object ItemsSource
    {
        get { return (object)GetValue(ItemsSourceProperty); }
        set { SetValue(ItemsSourceProperty, value); }
    }

    public static readonly DependencyProperty ItemsSourceProperty =
        DependencyProperty.Register("ItemsSource", typeof(object),
        typeof(ScrollToBottomBehavior),
        new PropertyMetadata(null, ItemsSourcePropertyChanged));

    private static void ItemsSourcePropertyChanged(object sender,
        DependencyPropertyChangedEventArgs e)
    {
        var behavior = sender as ScrollToBottomBehavior;
        if (behavior.AssociatedObject == null || e.NewValue == null) return;

        var collection = behavior.ItemsSource as INotifyCollectionChanged;
        if (collection != null)
        {
            collection.CollectionChanged += (s, args) =>
            {
                var scrollViewer = behavior.AssociatedObject
                                           .GetFirstDescendantOfType<ScrollViewer>();
                scrollViewer.ChangeView(null, scrollViewer.ActualHeight, null);
            };
        }
    }

    public void Attach(DependencyObject associatedObject)
    {
        var control = associatedObject as ListView;
        if (control == null)
            throw new ArgumentException(
                "ScrollToBottomBehavior can be attached only to ListView.");

        AssociatedObject = associatedObject;
    }

    public void Detach()
    {
        AssociatedObject = null;
    }
}

The ScrollToBottomBehavior expects that the ItemsSource property is bound to an object that impletements the INotifyCollectionChanged interface (like ObservableCollection) and then registers for its CollectionChanged event (lines 22-25).

When such event occurs, we must scroll the ListView. Instead of using its ScrollIntoView method, like said before, we get the ScrollViewer that is contained in the ListView control (lines 27-28). GetFirstDescendantOfType is an extension method of the VisualTreeHelperExtensions class, part of the WinRT XAML Toolkit (you can grab only this class and add it to your project). We invoke the ChangeView method specifying the vertical offset to use: with ActualHeight, we scroll to the bottom of the control.

Now suppose we have the following ViewModel (we’re using MVVM Light Toolkit):

public class Question
{
    public string Name { get; set; }
    public string Text { get; set; }
    public DateTimeOffset Date { get; set; }
}

public class MainViewModel : ViewModelBase
{
    private ObservableCollection<Question> questions;
    public ObservableCollection<Question> Questions
    {
        get { return questions; }
        set { this.Set(ref questions, value); }
    }

    public RelayCommand AddQuestionCommand { get; set; }

    public MainViewModel()
    {
        Questions = new ObservableCollection<Question>();

        AddQuestionCommand = new RelayCommand(() =>
        {
            Questions.Add(new Question
            {
                Date = DateTime.Now,
                Name = "Name " + questions.Count,
                Text = "Question " + questions.Count
            });
        });
    }
}

We have an ObservableCollection and a Command to add items to it. We want to show the questions in a ListView that scrolls to bottom everytime a new item is added. So, we define the following XAML:

<Page
    ...
    xmlns:behaviors="using:QuestionsManager.Behaviors"
    xmlns:i="using:Microsoft.Xaml.Interactivity"
    ...>

    <Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
        ...

        <ListView ItemsSource="{Binding Questions}">
            <ListView.ItemTemplate>
                <DataTemplate>
                    <StackPanel Margin="0,5,0,0">
                        <TextBlock Text="{Binding Date}" Margin="0,0,5,0" />
                        <StackPanel Orientation="Horizontal" Margin="0,5,0,0">
                            <TextBlock Text="{Binding Name}" FontWeight="Bold"
                                       Margin="0,0,5,0" />
                            <TextBlock Text="{Binding Text}"  />
                        </StackPanel>
                    </StackPanel>
                </DataTemplate>
            </ListView.ItemTemplate>
            <i:Interaction.Behaviors>
                <behaviors:ScrollToBottomBehavior ItemsSource="{Binding Questions}"/>
            </i:Interaction.Behaviors>
        </ListView>
        <StackPanel Grid.Row="1">
            <Button Content="Add dummy question" Command="{Binding AddQuestionCommand}" />
        </StackPanel>
    </Grid>
</Page>

At lines 23-25, we have bound the ItemsSource property of ScrollToBottomBehavior to Questions (the same of the cointainer ListView). This is all we need to do in order to activate the automatic scrolling.

Categories: C#, MVVM, Windows Phone, WinRT

Behaviors to handle StatusBar and ProgressIndicator in Windows Phone 8.1 apps

11/09/2014 3 comments

The new StatusBar object in Windows Phone apps replaces the SystemTray from Windows Phone Silverlight apps. Unlike the SystemTray, the StausBar can only be accessed via code.

We can, however, define a behavior that allows to handle the StatusBar in XAML. After adding to the project the reference to the Behavior SDK, we can create the following class:

public class StatusBarBehavior : DependencyObject, IBehavior
{
    private const string IS_VISIBLE = "IsVisible";
    private const string FOREGROUND_COLOR = "ForegroundColor";
    private const string BACKGROUND_COLOR = "BackgroundColor";
    private const string BACKGROUND_OPACITY = "BackgroundOpacity";

    public DependencyObject AssociatedObject { get; private set; }

    public void Attach(DependencyObject associatedObject) { }

    public void Detach() { }

    public bool IsVisible
    {
        get { return (bool)GetValue(IsVisibleProperty); }
        set { SetValue(IsVisibleProperty, value); }
    }

    public static readonly DependencyProperty IsVisibleProperty =
        DependencyProperty.Register(IS_VISIBLE,
        typeof(bool),
        typeof(StatusBarBehavior),
        new PropertyMetadata(true, OnIsVisibleChanged));

    private static async void OnIsVisibleChanged(DependencyObject d,
        DependencyPropertyChangedEventArgs e)
    {
        var statusBar = StatusBar.GetForCurrentView();
        if ((bool)e.NewValue)
            await statusBar.ShowAsync();
        else
            await statusBar.HideAsync();
    }

    public Color ForegroundColor
    {
        get { return (Color)GetValue(ForegroundColorProperty); }
        set { SetValue(ForegroundColorProperty, value); }
    }

    public static readonly DependencyProperty ForegroundColorProperty =
        DependencyProperty.Register(FOREGROUND_COLOR,
        typeof(Color),
        typeof(StatusBarBehavior),
        new PropertyMetadata(null, OnForegroundColorChanged));

    private static void OnForegroundColorChanged(DependencyObject d,
        DependencyPropertyChangedEventArgs e)
    {
        StatusBar.GetForCurrentView().ForegroundColor = (Color)e.NewValue;
    }

    public Color BackgroundColor
    {
        get { return (Color)GetValue(BackgroundColorProperty); }
        set { SetValue(BackgroundColorProperty, value); }
    }

    public static readonly DependencyProperty BackgroundColorProperty =
        DependencyProperty.Register(BACKGROUND_COLOR,
        typeof(Color),
        typeof(StatusBarBehavior),
        new PropertyMetadata(null, OnBackgroundColorChanged));

    private static void OnBackgroundColorChanged(DependencyObject d,
        DependencyPropertyChangedEventArgs e)
    {
        var behavior = d as StatusBarBehavior;
        if (behavior.BackgroundOpacity == 0)
            behavior.BackgroundOpacity = 1;

        StatusBar.GetForCurrentView().BackgroundColor = behavior.BackgroundColor;
    }

    public double BackgroundOpacity
    {
        get { return (double)GetValue(BackgroundOpacityProperty); }
        set { SetValue(BackgroundOpacityProperty, value); }
    }

    public static readonly DependencyProperty BackgroundOpacityProperty =
        DependencyProperty.Register(BACKGROUND_OPACITY,
        typeof(double),
        typeof(StatusBarBehavior),
        new PropertyMetadata(null, OnBackgroundOpacityChanged));

    private static void OnBackgroundOpacityChanged(DependencyObject d,
        DependencyPropertyChangedEventArgs e)
    {
        var behavior = d as StatusBarBehavior;
        StatusBar.GetForCurrentView().BackgroundOpacity = behavior.BackgroundOpacity;
    }
}

The new StatusBar is exposed via the static StatusBar.GetForCurrentView() method, that gets the status bar for the current window (app view). So, it is impossible to directly access it in XAML. This behavior provides 4 dependency properties to workaround this limitation. As the StatusBar is exposed via a static property, we don’t need to explicitly handle the Attach method.

For example, the OnIsVisibleChanged method (lines 26-33), invoked when the IsVisible property changes, calls the ShowAsync or HideAsync method. The same approach is followed by the other properties.

Similarly, the StatusBar ProgressIndicator can be accessed only via code, because it is exposed by the StatusBar.GetForCurrentView().ProgressIndicator property. So, also in this case we can define a behavior to use it in XAML:

public class ProgressIndicatorBehavior : DependencyObject, IBehavior
{
    private const string IS_VISIBLE = "IsVisible";
    private const string TEXT = "Text";
    private const string VALUE = "Value";
    private const string IS_INDETERMINATE = "IsIndeterminate";

    public DependencyObject AssociatedObject { get; private set; }

    public void Attach(DependencyObject associatedObject) { }

    public void Detach() { }

    public bool IsVisible
    {
        get { return (bool)GetValue(IsVisibleProperty); }
        set { SetValue(IsVisibleProperty, value); }
    }

    public static readonly DependencyProperty IsVisibleProperty =
        DependencyProperty.Register(IS_VISIBLE,
        typeof(bool),
        typeof(ProgressIndicatorBehavior),
        new PropertyMetadata(false, OnIsVisibleChanged));

    private static async void OnIsVisibleChanged(DependencyObject d,
        DependencyPropertyChangedEventArgs e)
    {
        var progressIndicator = StatusBar.GetForCurrentView().ProgressIndicator;
        if ((bool)e.NewValue)
        {
            progressIndicator.ProgressValue = 0;
            await progressIndicator.ShowAsync();
        }
        else
        {
            await progressIndicator.HideAsync();
        }
    }

    public string Text
    {
        get { return (string)GetValue(TextProperty); }
        set { SetValue(TextProperty, value); }
    }

    public static readonly DependencyProperty TextProperty =
        DependencyProperty.Register(TEXT,
        typeof(string),
        typeof(ProgressIndicatorBehavior),
        new PropertyMetadata(null, OnTextChanged));

    private static void OnTextChanged(DependencyObject d,
        DependencyPropertyChangedEventArgs e)
    {
        ProgressIndicatorBehavior behavior = (ProgressIndicatorBehavior)d;
        StatusBar.GetForCurrentView().ProgressIndicator.Text = behavior.Text;
    }

    public object Value
    {
        get { return (double?)GetValue(ValueProperty); }
        set { SetValue(ValueProperty, value); }
    }

    public static readonly DependencyProperty ValueProperty =
         DependencyProperty.Register(VALUE,
         typeof(object),
         typeof(ProgressIndicatorBehavior),
         new PropertyMetadata(null, OnValueChanged));

    private static void OnValueChanged(DependencyObject d,
        DependencyPropertyChangedEventArgs e)
    {
        double? val = null;
        if (e.NewValue != null)
            val = (double?)Convert.ToDouble(e.NewValue);

        StatusBar.GetForCurrentView().ProgressIndicator.ProgressValue = val;
    }

    public bool IsIndeterminate
    {
        get { return (bool)GetValue(IsIndeterminateProperty); }
        set { SetValue(IsIndeterminateProperty, value); }
    }

    public static readonly DependencyProperty IsIndeterminateProperty =
         DependencyProperty.Register(IS_INDETERMINATE,
         typeof(bool),
         typeof(ProgressIndicatorBehavior),
         new PropertyMetadata(false, OnIsIndeterminateChanged));

    private static void OnIsIndeterminateChanged(DependencyObject d,
        DependencyPropertyChangedEventArgs e)
    {
        var progressIndicator = StatusBar.GetForCurrentView().ProgressIndicator;
        if ((bool)e.NewValue)
            progressIndicator.ProgressValue = null;
        else
            progressIndicator.ProgressValue = 0;
    }
}

The behavior allows to set the text and the value of the indicator in XAML, accessing the underlying properties of the ProgressBarStatusIndicator object. Note that the Value property must be between 0 and 1 (it is a percentage). We can also use IsIndeterminate to show continuous progress feedback.

Using these behaviors is straightforward. Let’s see an example:

<Page
    x:Class="StatusBarDemo.MainPage"
    ...
    xmlns:i="using:Microsoft.Xaml.Interactivity"
    xmlns:behaviors="using:StatusBarDemo.Behaviors"
    >

    <i:Interaction.Behaviors>
        <behaviors:StatusBarBehavior IsVisible="True"
                                     ForegroundColor="White"
                                     BackgroundColor="Green"
                                     BackgroundOpacity="0.9" />
        <behaviors:ProgressIndicatorBehavior IsVisible="True"
                                             Text="StatusBar Demo"
                                             Value="0.6" />
    </i:Interaction.Behaviors>

This XAML produces the following results:

StatusBar in Windows Phone apps

StatusBar in Windows Phone apps

Moreover, because we have defined all dependency properties, we can use binding. Suppose we have a ViewModel and we want to set the ProgressIndicator to indeterminate state when, say, the IsBusy property is true:

<i:Interaction.Behaviors>
    ...
    <behaviors:ProgressIndicatorBehavior IsVisible="True" 
                                         Text="StatusBar Demo"
                                         IsIndeterminate="{Binding IsBusy}" />
</i:Interaction.Behaviors>

You can download a working example using the link below:

Behaviors to handle StatusBar and ProgressIndicator in Windows Phone 8.1 apps

Categories: C#, MVVM, Windows Phone

Drones on ioProgrammo

28/08/2014 Comments off

Drones have been sighted on n°193 of ioProgrammo (September/October 2014). On the magazine has been published an article in which I and my friend Marco Dal Pino talk about our experience interacting with the AR.Drone 2.0 by Parrot. We introduce the device and show how to manage it from Windows and Phone Store apps with the free library that we have relased on NuGet. Thanks to Intel RealSense, we also explain how to control its movements using hand gestures.

Our article on ioProgrammo

Our article on ioProgrammo

Categories: .NET, C#, Windows Phone, WinRT
Follow

Get every new post delivered to your Inbox.

Join 30 other followers