Archive

Archive for the ‘Universal Windows Platform’ Category

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

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.

Pay attention to .NET Native when using Reflection (MVVM scenario)

22/02/2016 Comments off

Among the other things, .NET Native tries to reduce the app size by analyzing the code and striping out unused .NET objects. This approach works very well, but we need to pay attention when we you work with Reflection, because in this case we must explicitly tell to .NET Native which elements are available for it.

A particular scenario occurs if we’re following the MVVM pattern and we have a classic app with a GridView or a ListView and we want to invoke a command when the user clicks an item, passing the item itself to the command. With the Universal Windows Platform, this task can be accomplished using an EventTriggerBehavoir form XamlBehavoirs along with an InvokeCommandAction and an InputConverter:

<GridView IsItemClickEnabled="True" ItemsSource="{Binding People}">
    <GridView.ItemTemplate>
        <DataTemplate>
            ...
        </DataTemplate>
    </GridView.ItemTemplate>

    <Interactivity:Interaction.Behaviors>
        <Interactions:EventTriggerBehavior EventName="ItemClick">
            <Interactions:InvokeCommandAction 
                Command="{Binding ItemSelectedCommand}" 
                InputConverter="{StaticResource EventArgsConverter}" 
                InputConverterParameter="ClickedItem" />
        </Interactions:EventTriggerBehavior>
    </Interactivity:Interaction.Behaviors>
</GridView>

At lines 9-14 we use an EventTriggerBehavior to catch the ItemClick event of the GridView and execute in response the ItemSelectedCommand action of the ViewModel. Thanks to InputConverter and InputConverterParamter (lines 12-13), this action automatically receives the clicked item as argument:

public sealed class EventArgsConverter : IValueConverter
{
    public object Convert(object value, Type targetType, object parameter, 
        string language)
    {
        if (value != null)
        {
            var propertyPath = parameter as string;
            if (!string.IsNullOrWhiteSpace(propertyPath))
            {
                var propertyPathParts = propertyPath.Split('.');
                object propertyValue = value;
                foreach (var propertyPathPart in propertyPathParts)
                {
                    var propInfo = propertyValue.GetType().GetTypeInfo().
                        GetDeclaredProperty(propertyPathPart);

                    propertyValue = propInfo.GetValue(propertyValue);
                }

                return propertyValue;
            }
        }

        return value;
    }

    public object ConvertBack(object value, Type targetType, object parameter, 
        string language)
    {
        throw new NotImplementedException();
    }
}

This Converter extracts the property name of the event argument that is passed as parameter (line 8, in this case ClickedItem) and then uses Reflection (lines 15-18) to get the actual value that will be received by the command.

This code works without problem in Debug mode, but when we switch to Release, enabling the .NET Native toolchain (that is required for app submission), if we click an item on the grid we’ll get a runtime error like the following one:

Unhandled exception at 0x77026D7E (combase.dll)

This occurs because the .NET Native toolchain has removed the ItemClickEventArgs class from the compiled code, as it hasn’t found any reference to it in the code, because it is accessed only at runtime through Reflection.

So, as said at the beginning we need to tell to .NET Native to keep this type during compilation. Let’s open the file Default.rd.xml inside the project Properties folder: it contains the Runtime Directives for .NET Native. All that we need is to add a declaration for the ItemClickEventArgs type:

<Directives xmlns="http://schemas.microsoft.com/netfx/2013/01/metadata">
    <Application>
        <!--
          An Assembly element with Name="*Application*" applies to all 
          assemblies in the application package. The asterisks are not 
          wildcards.
        -->
        
        <Assembly Name="*Application*" Dynamic="Required All" />

        <!-- Add your application specific runtime directives here. -->
        <Type Name="Windows.UI.Xaml.Controls.ItemClickEventArgs" 
              Dynamic="Required Public" />

    </Application>
</Directives>

At lines 12-13 we have specified that we want to keep the ItemClickEventArgs type in compilation, even if it isn’t statically referenced in the code. Now we can compile the app in Release mode again: this time everything will work as expected.

We can refer to MSDN documentation to get more information about the Runtime Directives Configuration File.

Using MVVM Light ViewModelBase class with Template 10

25/01/2016 1 comment

Template10 comes with a handful ViewModelBase class that provides an easy way to handle events such as OnNavigatedTo, OnNavigatingFrom, access the Navigation Service from View Models and so on. In the previous posts we have seen how to integrate this class with MVVM Light, but what if we already have View Models that inherit from MVVM Light ViewModelBase, or as usually happens we have our ViewModelBase class, that in turns inherits from MVVM Light one?

If our View Models directly inherit from MVVM Light ViewModelBase class, we simply need to implement the Template 10 INavigable interface:

public class MainViewModel : GalaSoft.MvvmLight.ViewModelBase,
    Template10.Services.NavigationService.INavigable
{
    public Task OnNavigatedToAsync(object parameter, NavigationMode mode, 
        IDictionary<string, object> state)
    {
        // ...
        return Task.CompletedTask;
    }

    public Task OnNavigatedFromAsync(IDictionary<string, object> state, 
        bool suspending)
    {
        // ...
        return Task.CompletedTask;
    }

    public Task OnNavigatingFromAsync(NavigatingEventArgs args)
    {
        // ...
        return Task.CompletedTask;
    }

    [JsonIgnore]
    public IDispatcherWrapper Dispatcher { get; set; }

    [JsonIgnore]
    public INavigationService NavigationService { get; set; }

    [JsonIgnore]
    public IStateItems SessionState { get; set; }
}

In this case the recommended approach is of course to create a base class that inherits from MVVM Light ViewModelBase class and implements the Template 10 INavigable interface:

public abstract class MyViewModelBase : GalaSoft.MvvmLight.ViewModelBase,
    Template10.Services.NavigationService.INavigable
{
    public virtual Task OnNavigatedToAsync(object parameter, 
        NavigationMode mode, IDictionary<string, object> state) 
        => Task.CompletedTask;

    public virtual Task OnNavigatedFromAsync(IDictionary<string, object> state,
        bool suspending) 
        => Task.CompletedTask;

    public virtual Task OnNavigatingFromAsync(NavigatingEventArgs args)
        => Task.CompletedTask;

    [JsonIgnore]
    public IDispatcherWrapper Dispatcher { get; set; }

    [JsonIgnore]
    public INavigationService NavigationService { get; set; }

    [JsonIgnore]
    public IStateItems SessionState { get; set; }
}

As said before, if we already have our custom ViewModelBase class, we just need to make it implement the INavigable interface in the same way. In any cases, after defining this class, we can use it as usual:

public class MainViewModel : MyViewModelBase
{
    private string name;
    public string Name
    {
        get { return name; }
        set { base.Set(ref name, value, broadcast: true); }
    }

    public override Task OnNavigatedToAsync(object parameter,
        NavigationMode mode, IDictionary<string, object> state)
    {
        var argument = parameter?.ToString();

        if (state.Any())
        {
            //...

            state.Clear();

        }

        // Calls a method from MVVM Light ViewModelBase class.
        base.Broadcast(null, "Marco", nameof(Name));

        return base.OnNavigatedToAsync(parameter, mode, state);
    }
}

We can now access all the features provided by either MVVM Light and Template 10 without further code refactoring.