Real-time voice translation with Microsoft Translator on ioProgrammo

26/06/2017 1 comment

I have written a new article for the n°215 of ioProgrammo (July 2017). This time I show how to use Microsoft Translator Speech API to build a real-time voice translation app for the Universal Windows Platform.

ioProgrammo July 2017

ioProgrammo July 2017

Here it is a short video showing the project that comes with the article:

Advertisements

Two hidden gems in the Universal Windows Platform

22/05/2017 2 comments

Even if the Creators Update version of Windows 10 has been released a couple of month ago and we’re waiting for the next Fall Creators Update, there is still room to talk about the Anniversary Edition, because it contains a couple of gems that not many people know about.

Raise your hand if you never had a BooleanToVisibilityConverter class in any of your apps. It is necessary because the Visibility property of UIElement is an Enum, but tipically, in particular when we’re following the MVVM pattern, we just have a Boolean property that we want to use to control the visibility of an object. In this case, we could add a BooleanToVisibilityConverter class to our app, like the following one:

public sealed class BooleanToVisibilityConverter : IValueConverter
{
    public object Convert(object value, Type targetType, object parameter, 
        string language)
    {
        return (value is bool && (bool)value) 
            ? Visibility.Visible : Visibility.Collapsed;
    }

    public object ConvertBack(object value, Type targetType, object parameter, 
        string language)
    {
        return value is Visibility && (Visibility)value == Visibility.Visible;
    }
}

Of course, there could be other implementations, or we could use an attached property instead of a Converter, but the scenario remains the same.

Starting from Windows 10, version 1607 (i.e., the Anniversary Edition) this is no longer necessary. In fact, if we use the {x:Bind} markup extension (that was first introduced in the initial release of Windows 10), we can cast a Boolean property to a Visibility value directly in the XAML defition:

<Image Source="Assets/Favorite.png" 
       Visibility="{x:Bind (Visibility)ViewModel.IsFavorited}" />

The meaning of this declaration is straightforward: if ViewModel.IsFavorited is true, it returns Visibility.Visible, otherwise Visibility.Collapsed. In this way, we do not need any extra class anymore.

But there is another cool feature that helps us solving a common problem. If we’re developing a “chat-like” app, we tipically have a ListView in which we add items to the bottom. In this scenario, we often have the requirement to automatically scroll the ListView as new items are inserted, so that the last ones are always visible. To obtain this, we could add a ScroolToBottom Behavior class to our app.

Again, with the Anniversary Edition we can set the ItemsUpdatingScrollMode property of the ItemsStackPanel to KeepLastItemInView, that adjusts the scroll offset to keep the last visible item showing at the bottom of the view. In other words, we just need to set the ItemsPanelTemplate of the ListView in this way:

<ListView ItemsSource="{x:Bind ViewModel.Samples}">
    ...
    <ListView.ItemsPanel>
        <ItemsPanelTemplate>
            <ItemsStackPanel ItemsUpdatingScrollMode="KeepLastItemInView" />
        </ItemsPanelTemplate>
    </ListView.ItemsPanel>
</ListView>

And the list will automatically scroll to bottom as new items are added to it. No code at all is needed to implement this behavior.

You can download a sample of these features using the link below:
Anniversay Update Cool Features

Microsoft Translator Service on ioProgrammo

16/02/2017 2 comments

I have written a new article for the n°211 of ioProgrammo (February/March 2017). This time I introduce my Translator Service Library and show how to use it to build a chat with real-time translation capabilities.

ioProgrammo February/March 2017

ioProgrammo February/March 2017

Here it is a short video showing the project that comes with the article:

How to shutdown a Windows 10 IoT Core device from a UWP app

13/12/2016 1 comment

When dealing with an embedded device, we may have the need to turn it off. The same is true for Windows 10 IoT Core devices: in fact, the DefaultApp and the Device Portal have an option that allows to shutdown or restart the board. So, if we deploy our app, how can we implement this feature?

First of all, we need to add the Windows IoT Extensions for the UWP to our project:

Windows IoT Extensions for the UWP

Windows IoT Extensions for the UWP

In this way, we have access to the Windows.System.ShutdownManager class, that we can use to manage the shutdown of devices. It exposes two static methods:

So, for example:

// Shutdowns the device immediately:
ShutdownManager.BeginShutdown(ShutdownKind.Shutdown, TimeSpan.FromSeconds(0));

// Restarts the device within 5 seconds:
ShutdownManager.BeginShutdown(ShutdownKind.Restart, TimeSpan.FromSeconds(5));

In order for this code to work properly, we need also to give an extra capability to our app. Let’s open the Package.appxmanifest file with the Visual Studio XML Editor and add or update the following values:

<Package
         ...
         xmlns:iot="http://schemas.microsoft.com/appx/manifest/iot/windows10"
         IgnorableNamespaces="uap mp iot">
  
  <Capabilities>
    ...
    <iot:Capability Name="systemManagement" />
  </Capabilities>
</Package>

If we don’t set this capability, we’ll get an UnauthorizedAccessException error when calling ShutdownManager methods.Beg

Xamarin.Forms and Azure Mobile apps on ioProgrammo

08/09/2016 1 comment

I have written a new article for the n°206 of ioProgrammo (September 2016). This time I talk about Xamarin.Forms and how to use it together with Azure Mobile apps in order to create an app that is strictly integrated with Facebook.

ioProgrammo September 2016

ioProgrammo September 2016

Categories: .NET, Azure, C#, General, Xamarin

A simple NavigationService for Xamarin.Forms

11/07/2016 1 comment

If we do a search on the Internet, we’ll find a lot of implementations of a NavigationService for Xamarin.Forms. While all of them are surely valid, there are two things that I don’t like much:

  • if we want to pass arguments to the new page, we need to use the constructor of the page itself (i.e., adding an object parameter to it);
  • they don’t provide a convenient way to clear navigation history, that is often a requirement (i.e., after login/registration).

So, I ended up writing my own implementation. It is very simple and doesn’t cover all the scenarios, but at this moment it completely satifies my need:

public class NavigationService
{
    private Dictionary<string, Type> pages { get; }
        = new Dictionary<string, Type>();

    public Page MainPage => Application.Current.MainPage;

    public void Configure(string key, Type pageType) => pages[key] = pageType;

    public void GoBack() => MainPage.Navigation.PopAsync();

    public void NavigateTo(string pageKey, object parameter = null,
        HistoryBehavior historyBehavior = HistoryBehavior.Default)
    {
        Type pageType;
        if (pages.TryGetValue(pageKey, out pageType))
        {
            var displayPage = (Page)Activator.CreateInstance(pageType);
            displayPage.SetNavigationArgs(parameter);

            if (historyBehavior == HistoryBehavior.ClearHistory)
            {
                MainPage.Navigation.InsertPageBefore(displayPage,
                    MainPage.Navigation.NavigationStack[0]);

                var existingPages = MainPage.Navigation.NavigationStack.ToList();
                for (int i = 1; i < existingPages.Count; i++)
                    MainPage.Navigation.RemovePage(existingPages[i]);
            }
            else
            {
                MainPage.Navigation.PushAsync(displayPage);
            }
        }
        else
        {
            throw new ArgumentException($"No such page: {pageKey}.",
                nameof(pageKey));
        }
    }
}

public enum HistoryBehavior
{
    Default,
    ClearHistory
}

public static class NavigationExtensions
{
    private static ConditionalWeakTable<Page, object> arguments
        = new ConditionalWeakTable<Page, object>();

    public static object GetNavigationArgs(this Page page)
    {
        object argument = null;
        arguments.TryGetValue(page, out argument);

        return argument;
    }

    public static void SetNavigationArgs(this Page page, object args)
        => arguments.Add(page, args);
}

The idea of this NavigationService is to first register all the pages using the Configure method (line 8), just like the MVVM Light approach. The core of the implementation is the NavigateTo method (lines 12-41). It tries to get the page type corresponding the passed key (line 16) and then instantiate it using Activator.CreateInstance.

This is the first difference with other solutions: we create the page using its default parameterless constructor. The actual parameter, if any, is stored in a kind of Dictionary using the SetNavigationArgs extension method at line 19 (its implementation is at lines 62-63).

Then, we check whether we want to clear history after navigation: if this case, we insert the new page before the current one (lines 23-24) and then, at lines 26-28, we remove all the other pages from the stack. Otherwise, at line 32 we just perform a normal PushAsync of the page.

Let’s see how to use it. First of all, we configure the NavigationService in the App class:

public partial class App : Application
{
    public static NavigationService NavigationService { get; }
        = new NavigationService();

    public App()
    {
        InitializeComponent();

        NavigationService.Configure("MainPage", typeof(MainPage));
        NavigationService.Configure("SecondPage", typeof(SecondPage));
        NavigationService.Configure("ThirdPage", typeof(ThirdPage));

        MainPage = new NavigationPage(new MainPage());
    }
}

Then, in MainPage.xaml we write something like this:

<StackLayout Margin="12" HorizontalOptions="Center">
  <Entry x:Name="arguments" Placeholder="Arguments..." />
  <StackLayout Orientation="Horizontal" Spacing="0">
    <Label Text="Clear History" VerticalOptions="Center" Margin="0,0,10,0" />
    <Switch x:Name="clearHistory" VerticalOptions="Center" />
  </StackLayout>
  <Button x:Name="navigate" Text="Go to second page" Clicked="navigate_Clicked" />
</StackLayout>

So we have an Entry that allows to specify arguments to be passed to the target (line 2), a Switch to clear history after navigation (line 5) and a Button to actually go to the second page (line 7). The corresponding code-behind follows:

private void navigate_Clicked(object sender, EventArgs e)
{
    var historyBehavior = clearHistory.IsToggled
        ? HistoryBehavior.ClearHistory : HistoryBehavior.Default;

    App.NavigationService.NavigateTo("SecondPage", arguments.Text, 
        historyBehavior);
}

We simply get the HistoryBehavior based on Switch value and then we pass it along with the target page and the arguments to the NavigateTo method. Finally, in the Second Page we override the OnAppearing method:

protected override void OnAppearing()
{
    var args = this.GetNavigationArgs();
    passedArguments.Text = $"Passed arguments: {args}";

    base.OnAppearing();
}

Using the GetNavigationArgs extension method, at line 3 we retrieve the arguments we have specified with NavigateTo.

Another interesting point about this solution is that it can easily be integrated with an MVVM approach, but we’ll go deeper in this argument in a future post.

You can download the complete example using the link below:
A simple NavigationService for Xamarin.Forms

Categories: C#, Xamarin

A Behavior for CameraPressed event in Universal Windows apps

30/05/2016 1 comment

If we’re developing a Universal app that uses the camera, on Windows Mobile we may want to use the hardware camera button for example to take a photo. Of course, we need to take into account that on desktops and tablets we don’t have this feature. To add a bit more complexity, suppose we’re following the MVVM pattern. So, how can we manage this scenario?

In order to handle the hardware camera button, we just need a reference to the Windows Mobile Extensions for the UWP. In this way, we obtain access to Mobile specific features:

Windows Mobile Extensions for the UWP

Windows Mobile Extensions for the UWP

As we’re working with MVVM, the best solution is to create a custom Behavior. First of all, let’s add its reference through NuGet, searching for the package Microsoft.Xaml.Behaviors.Uwp.Managed:

UWP Behavoirs package on NuGet

UWP Behavoirs package on NuGet

Now we have all the prerequisites to create the CameraPressedBehavior:

[ContentProperty(Name = "Actions")]
public sealed class CameraPressedBehavior : Behavior
{
    public static readonly DependencyProperty ActionsProperty = 
        DependencyProperty.Register(
        "Actions",
        typeof(ActionCollection),
        typeof(CameraPressedBehavior),
        new PropertyMetadata(null));

    public ActionCollection Actions
    {
        get
        {
            var actionCollection = (ActionCollection)
                this.GetValue(ActionsProperty);

            if (actionCollection == null)
            {
                actionCollection = new ActionCollection();
                this.SetValue(ActionsProperty, actionCollection);
            }

            return actionCollection;
        }
    }

    [System.Runtime.CompilerServices.PlatformSpecific]
    private readonly bool isTypePresent;

    public CameraPressedBehavior()
    {
        isTypePresent = 
            Windows.Foundation.Metadata.ApiInformation.IsTypePresent(
                "Windows.Phone.UI.Input.HardwareButtons");
    }

    protected override void OnAttached()
    {
        base.OnAttached();

        if (isTypePresent)
            HardwareButtons.CameraPressed += HardwareButtons_CameraPressed;
    }

    protected override void OnDetaching()
    {
        base.OnDetaching();

        if (isTypePresent)
            HardwareButtons.CameraPressed -= HardwareButtons_CameraPressed;
    }

    private void HardwareButtons_CameraPressed(object sender, CameraEventArgs e)
    {
        Interaction.ExecuteActions(AssociatedObject, Actions, EventArgs.Empty);
    }       
}

At lines 4-26 we define the Actions dependency property that stores the action to be executed when then button is pressed. This part of code is usually present in every behavior.

Then, in the Behavior costructor (lines 31-36), we use the ApiInformation.IsTypePresent method to check whether the Windows.Phone.UI.Input.HardwareButtons type is actually present, i.e. if the platform provides access to hardware buttons. If this is the case, in the OnAttached method (lines 38-44) we register for the CameraPressed event, otherwise we do nothing. In the same way, in the OnDetaching method we remove the event registration, if necessary. Thanks to these checks, the code can safely be executed also on platforms that don’t have hardware buttons.

Finally, in the CameraPressed event handler (lines 54-57), we call the Interaction.ExecuteActions static method, that in turn executes all the registered actions.

Now we can use the Behavior in our XAML page. For example:

<Page
    ...
    xmlns:Interactivity="using:Microsoft.Xaml.Interactivity" 
    xmlns:Interactions="using:Microsoft.Xaml.Interactions.Core"
    xmlns:behaviors="using:See4Me.Behaviors"
    ...>

    <Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
        ...
        <Interactivity:Interaction.Behaviors>
            <behaviors:CameraPressedBehavior>
                <Interactions:InvokeCommandAction 
                              Command="{Binding TakePhotoCommand}"  />
            </behaviors:CameraPressedBehavior>            
        </Interactivity:Interaction.Behaviors>
    </Grid>
</Page>

We add the CameraPressedBehavoir to the page (lines 10-15) so that, when the button is pressed, the InvokeCommandAction is executed, causing the TakePhotoCommand to be run. As said before, this behavior on desktops and tables has no effects, so it actually works only on phones.