Archive

Archive for the ‘.NET’ Category

Custom Vision Companion on ioProgrammo

20/10/2017 Leave a comment

I have written a new article for the n°219 of ioProgrammo (November 2017). I talk about Custom Vision Service and show how to build a Universal Windows Platform app that uses these APIs to get predictions from images and photos taken in the real world.

ioProgrammo n°219 (November 2017)

ioProgrammo n°219 (November 2017)

The app described in the article, Custom Vision Companion, is open source and is available on GitHub.

Advertisements

How to handle navigation events in MVVM using Windows Template Studio

17/10/2017 1 comment

Windows Template Studio is a Visual Studio 2017 Extension that accelerates the creation of new Universal Windows Platform (UWP) apps using a wizard-based experience.
Among the other things, it allows to use the MVVM pattern with a simple selection in the wizard, by providing a basic implementation rather than using MVVM Light. This approach avoids writing a lot of boilerplate code, but if we choose it, we’ll discover that an important feature is currently missing: the ability to automatically calls methods on ViewModels when we navigate to/from a Page.
However, adding this behavior is quite simple. We just need to add an INavigable interface to the project:

public interface INavigable
{
    Task OnNavigatedToAsync(object parameter, NavigationMode mode);

    void OnNavigatingFrom(NavigatingCancelEventArgs e);

    void OnNavigatedFrom();
}

Then, we have to edit the NavigationServices.Ex class, that is placed in the Services folder. First of all, we need to add the registration/deregistration methods for the Frame.Navigating event in the RegisterFrameEvents and UnregisterFrameEvents methods:

private void RegisterFrameEvents()
{
    if (_frame != null)
    {
        _frame.Navigating += Frame_Navigating;
        _frame.Navigated += Frame_Navigated;
        _frame.NavigationFailed += Frame_NavigationFailed;
    }
}

private void UnregisterFrameEvents()
{
    if (_frame != null)
    {
        _frame.Navigating -= Frame_Navigating;
        _frame.Navigated -= Frame_Navigated;
        _frame.NavigationFailed -= Frame_NavigationFailed;
    }
}

Then, let’s add the Frame_Navigating event handler and modify the existing Frame_Navigated as follows:

private void Frame_Navigating(object sender, NavigatingCancelEventArgs e)
{
    var dataContext = ResolveForPage(Frame.Content as Page);
    if (dataContext != null)
    {
        dataContext.OnNavigatingFrom(e);
        if (!e.Cancel)
        {
            dataContext.OnNavigatedFrom();
        }
    }
}

private async void Frame_Navigated(object sender, NavigationEventArgs e)
{
    Navigated?.Invoke(sender, e);

    var dataContext = ResolveForPage(e.Content as Page);
    if (dataContext != null)
    {
        await dataContext.OnNavigatedToAsync(e.Parameter, e.NavigationMode)
            .ConfigureAwait(false);
    }
}

private INavigable ResolveForPage(Page page)
    => (page?.DataContext as INavigable);

In the first event, if the DataContext (i.e., the ViewModel) of the Page implements the INavigable interface, we call its OnNavigatingFrom method, passing the NavigatingCancelEventArgs to it. So, if we set its Cancel property to true, we can cancel the navigation back. Otherwise, we then call the OnNavigatedFrom method.
On the other hand, when we navigate to a page, the Frame_Navigated event handler is invoked. In this case, we try to call the OnNavigateToAsync method, passing parameters and NavigationMode to it.

Now everything is ready. We can for example write something like this:

public class MainViewModel : ViewModelBase, INavigable
{
    // ...

    public Task OnNavigatedToAsync(object parameter, NavigationMode mode)
    {
        return Task.CompletedTask;
    }

    public void OnNavigatingFrom(NavigatingCancelEventArgs e)
    {
    }

    public void OnNavigatedFrom()
    {
    }
}

We don’t need anything else. We can simply set breakpoints on these methods and see that they are invoked when we navigate to/from the corresponding page. Of course, we can define our own ViewModelBase class that already implements the INavigable interface, so we have to override only the navigation methods we really need.

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:

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:

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

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.

Binding to Enum in Universal apps with localization

19/03/2015 1 comment

When we work with enums, we may want to display description messages associated to symbolic names. For example, suppose we have the following model in our app that uses the MVVM pattern:

public enum Status
{
    Free,
    NotAvailable,
    DoNotDisturb
}

public class Contact
{
    public string FirstName { get; set; }
    public string LastName { get; set; }
    public Status CurrentStatus { get; set; }
}

If we bind the CurrentStatus property of Contact class, the desired result is to have values such as Free, Not Available and Do Not Disturb.

This task can be simply accomplished using Custom Attributes and a Converter. First of all, create a Display attribute and use it to decorate the enum:

public class DisplayAttribute : Attribute
{
    public string Name { get; private set; }

    public DisplayAttribute(string name)
    {
        Name = name;
    }
}

public enum Status
{
    [Display("Free")]
    Free,
    [Display("Not Available")]
    NotAvailable,
    [Display("Do Not Disturb")]
    DoNotDisturb
}

Then, we define the following Converter:

public class EnumToStringConverter : IValueConverter
{
    public object Convert(object value, Type targetType, object parameter, string language)
    {
        if (value == null || !(value is Enum))
            return null;

        var @enum = value as Enum;
        var description = @enum.ToString();

        var attrib = this.GetAttribute<DisplayAttribute>(@enum);
        if (attrib != null)
            description = attrib.Name;

        return description;
    }

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

    private T GetAttribute<T>(Enum enumValue) where T : Attribute
    {
        return enumValue.GetType().GetTypeInfo()
            .GetDeclaredField(enumValue.ToString())
            .GetCustomAttribute<T>();
    }
}

At line 11 we check whether the enum value is decorated with the Display attribute. If so, we retrieve its Name property, that contains the actual string we want to use.

The last thing to do is to use the EnumToStringConverter in our binding declaration. For example:

<TextBlock Text="{Binding CurrentStatus, 
    Converter={StaticResource EnumToStringConverter}}" />

And what’s about localization? In a real world scenario we want strings localized according to user culture. Thanks to the built-in support in WinRT, this is straightforward. We just need to modify a bit our Converter:

public class EnumToStringConverter : IValueConverter
{
    public object Convert(object value, Type targetType, object parameter, string language)
    {
        if (value == null || !(value is Enum))
            return null;

        var @enum = value as Enum;
        var description = @enum.ToString();

        var attrib = this.GetAttribute<DisplayAttribute>(@enum);
        if (attrib != null)
        {
            var resource = new ResourceLoader();
            if (!string.IsNullOrWhiteSpace(resource.GetString(attrib.Name)))
                description = resource.GetString(attrib.Name);
            else
                description = attrib.Name;
        }

        return description;
    }

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

    private T GetAttribute<T>(Enum enumValue) where T : Attribute
    {
        return enumValue.GetType().GetTypeInfo()
            .GetDeclaredField(enumValue.ToString())
            .GetCustomAttribute<T>();
    }
}

At lines 14-16 we create a ResourceLoader and try to get the string that corresponds to the Name property of the attribute. So, to enable localization of enum values we simply need to add a Resource file (resw) for each language and define resource names accordingly.

If, instead, the string isn’t found with the ResourceLoader, the original Display.Name property is used (line 18), as in the first version of the Converter.

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