Archive

Archive for the ‘.NET’ 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:

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

How to open and close Flyouts in Universal apps using MVVM

15/01/2015 6 comments

Some times ago we talked about how to open attached Flyouts and close them using custom behaviors and MVVM. This was necessary because the Flyout control doesn’t expose properties to control its visibility, so we need to use its ShowAt and Hide methods explicitly.

While this approach works correctly, we can obtain the same result in a more elegant way with two simple Attached Properties. The following is a generic version of the implementation shown in the article Using Windows 8.1 Flyout with MVVM and works with every control, not only buttons (remember, in fact, that we can attach a Flyout on any FrameworkElement).

Let’s start creating a FlyoutHelper class:

public static class FlyoutHelper
{
    public static readonly DependencyProperty IsVisibleProperty = 
        DependencyProperty.RegisterAttached(
        "IsOpen", typeof(bool), typeof(FlyoutHelper), 
        new PropertyMetadata(true, IsOpenChangedCallback));

    public static readonly DependencyProperty ParentProperty = 
        DependencyProperty.RegisterAttached(
        "Parent", typeof(FrameworkElement), typeof(FlyoutHelper), null);

    public static void SetIsOpen(DependencyObject element, bool value)
    {
        element.SetValue(IsVisibleProperty, value);
    }

    public static bool GetIsOpen(DependencyObject element)
    {
        return (bool)element.GetValue(IsVisibleProperty);
    }

    private static void IsOpenChangedCallback(DependencyObject d, 
        DependencyPropertyChangedEventArgs e)
    {
        var fb = d as FlyoutBase;
        if (fb == null)
            return;

        if ((bool)e.NewValue)
        {
            fb.Closed += flyout_Closed;
            fb.ShowAt(GetParent(d));
        }
        else
        {
            fb.Closed -= flyout_Closed;
            fb.Hide();
        }
    }

    private static void flyout_Closed(object sender, object e)
    {
        // When the flyout is closed, sets its IsOpen attached property to false.
        SetIsOpen(sender as DependencyObject, false);
    }

    public static void SetParent(DependencyObject element, FrameworkElement value)
    {
        element.SetValue(ParentProperty, value);
    }

    public static FrameworkElement GetParent(DependencyObject element)
    {
        return (FrameworkElement)element.GetValue(ParentProperty);
    }
}

This code adds an IsOpen Attached Property to flyout objects. When it changes (lines 22-39), we check whether we want to open or close the Flyout: in the first case, we call the ShowAt method (lines 32), that actually displays it. Since this method requires a FrameworkElement that represents the flyout’s placement target, we need also to specify the target control for the popup, so we have defined a Dependecy Property named Parent that holds the container of the Flyout. If, instead, we are about to dismiss the control, when IsOpen is set to false, we invoke its Hide method (line 37).

Note that we also need to register for the Closed event (line 31), that occurs when the flyout is hidden. The Flyout, in fact, implements the light-dismiss behavior: it can be closed simply touching anywhere on the screen outside of it, so it is necessary to handle the Closing event and set the IsOpen property to false, to reflect the correct state of the Flyout.

Now we can define a ViewModel like this:

public class MainViewModel : ViewModelBase
{
    private bool isOpen;
    public bool IsOpen
    {
        get { return isOpen; }
        set { this.Set(ref isOpen, value); }
    }

    public RelayCommand OpenCommand { get; set; }
    public RelayCommand CloseCommand { get; set; }

    public MainViewModel()
    {
        OpenCommand = new RelayCommand(() => IsOpen = true);
        CloseCommand = new RelayCommand(() => IsOpen = false);
    }
}

We have a command to open the Flyout (setting the IsOpen variable to true, line 15) and, similarly, a command to close it (line 16). In this way, in the View we can use the following XAML:

<Button Content="Open Flyout" x:Name="button" Command="{Binding OpenCommand}">
    <FlyoutBase.AttachedFlyout>
        <Flyout controls:FlyoutHelper.IsOpen="{Binding IsOpen, Mode=TwoWay}" 
                controls:FlyoutHelper.Parent="{Binding ElementName=button}">
            <StackPanel>
                <TextBlock Text="Awesome Flyout!" Margin="10" />
                <Button Content="Close" Command="{Binding CloseCommand}" 
                        HorizontalAlignment="Right" />
            </StackPanel>
        </Flyout>
    </FlyoutBase.AttachedFlyout>
</Button>

Moveover, using the Behavior SDK, we can use the same approach to attach a Flyout to any control:

<Page
    ...
    xmlns:i="using:Microsoft.Xaml.Interactivity"
    xmlns:core="using:Microsoft.Xaml.Interactions.Core"
    ...>

    ...
    <Image x:Name="image" Source="/Assets/Logo.scale-100.png" 
           Height="100" Width="100">
        <FlyoutBase.AttachedFlyout>
            <Flyout controls:FlyoutHelper.IsOpen="{Binding IsOpen, Mode=TwoWay}" 
                    controls:FlyoutHelper.Parent="{Binding ElementName=image}">
                <StackPanel>
                    <TextBlock Text="Awesome Flyout!" Margin="10" />
                    <Button Content="Close" Command="{Binding CloseCommand}" 
                            HorizontalAlignment="Right" />
                </StackPanel>
            </Flyout>
        </FlyoutBase.AttachedFlyout>
        <i:Interaction.Behaviors>
            <core:EventTriggerBehavior EventName="Tapped">
                <core:InvokeCommandAction Command="{Binding OpenCommand}" />
            </core:EventTriggerBehavior>
        </i:Interaction.Behaviors>
    </Image>
    ...
</Page>

The EventTriggerBehavior declared at lines 21-23 invokes the OpenCommand action as soon as the Tapped event raises. As seen before, this sets the IsOpen property of the ViewModel to true, so the Flyout attached property displays the popup.

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

Using “AndContinue” methods in Windows Phone Store apps with MVVM

07/01/2015 1 comment

As MSDN says, “Certain memory-intensive API on Windows Phone 8.1 contain AndContinue methods. When you call an AndContinue method, your app is deactivated while the operation completes in order to conserve memory. On low-memory devices, your app might even be terminated. Because of this possibility, you have to call different methods in a Windows Phone Store app than you call in a Windows Store app to continue your app after these operations.”.

This happens, for example, when we want to select an image using the FilePicker. On Windows Phone Store apps, we need to call the PickSingleAndContinue method. In this case, we have the problem to continue our apps after calling this method.

The topic How to continue your Windows Phone Store app after calling an AndContinue method on MSDN introduces the ContinuationManager, a class that works together with the SuspensionManager to make it easier to continue our app.

This code, however, is based on a code-behind approach. If we’re following the MVVM pattern, we need to change it in order to invoke continuation methods on a ViewModel. So, we can rewrite the Continue method as follows:

public class ContinuationManager
{
    // ...
    
    private FrameworkElement GetCurrentView()
    {
        var frame = Window.Current.Content as Frame;
        if (frame != null)
            return frame.Content as FrameworkElement;

        return Window.Current.Content as FrameworkElement;
    }

    internal void Continue(IContinuationActivatedEventArgs args)
    {
        var view = this.GetCurrentView();
        if (view == null)
            return;

        this.Continue(args, view.DataContext);
    }

    internal void Continue(IContinuationActivatedEventArgs args, object dataContext)
    {
        if (args == null)
            throw new ArgumentNullException("args");

        if (this.args != null)
            throw new InvalidOperationException("Can't set args more than once");

        this.args = args;
        this.id = Guid.NewGuid();

        if (dataContext == null)
            return;

        switch (args.Kind)
        {
            case ActivationKind.PickFileContinuation:
                var fileOpenPickerViewModel = dataContext as IFileOpenPickerContinuable;
                if (fileOpenPickerViewModel != null)
                    fileOpenPickerViewModel.ContinueFileOpenPicker
                        (args as FileOpenPickerContinuationEventArgs);
                break;

            case ActivationKind.PickSaveFileContinuation:
                var fileSavePickerViewModel = dataContext as IFileSavePickerContinuable;
                if (fileSavePickerViewModel != null)
                    fileSavePickerViewModel.ContinueFileSavePicker
                        (args as FileSavePickerContinuationEventArgs);
                break;

            case ActivationKind.PickFolderContinuation:
                var folderPickerViewModel = dataContext as IFolderPickerContinuable;
                if (folderPickerViewModel != null)
                    folderPickerViewModel.ContinueFolderPicker
                        (args as FolderPickerContinuationEventArgs);
                break;

            case ActivationKind.WebAuthenticationBrokerContinuation:
                var wabViewModel = dataContext as IWebAuthenticationContinuable;
                if (wabViewModel != null)
                    wabViewModel.ContinueWebAuthentication
                        (args as WebAuthenticationBrokerContinuationEventArgs);
                break;
        }
    }
}

The GetForCurrentView method, at lines 5-12, retrieves the view (i.e., the page) that is currently shown. Then, in the Continue method at lines 23-67, we check the Kind property of IContinuationActivatedEventArgs (that comes from the OnActivated method of App.xaml.cs file): based on its value, we try to cast the DataContext of the page (i.e., its ViewModel) to a particular interface (that is declared below in the file).

If the conversion succeeds, it means that the ViewModel supports this kind of continuation, so the corresponding method is invoked. For example, in case of PickFileContinuation (lines 39-44), we cast the DataContext to IFileOpenPickerContinuable and then call its ContinueFileOpenPicker method passing information about the selected file.

In this way, our ViewModel looks like (the example is based on MVVM Light):

public class PhotoViewModel : ViewModelBase, IFileOpenPickerContinuable
{
    private string photoPath;
    public string PhotoPath
    {
        get { return photoPath; }
        set { this.Set(ref photoPath, value); }
    }

    public RelayCommand SelectPhotoCommand { get; set; }

    public PhotoViewModel()
    {
        this.CreateCommands();
    }

    private void CreateCommands()
    {
        SelectPhotoCommand = new RelayCommand(() =>
        {
            // Calls the method that opens the FilePicker page.
            // When selected, the method "ContinueFileOpenPicker"
            // from IFileOpenPickerContinuable interface
            // will be invoked.
            var picker = new FileOpenPicker();

            picker.SuggestedStartLocation = PickerLocationId.PicturesLibrary;
            picker.SettingsIdentifier = "continuationmanagerdemo";
            picker.ViewMode = PickerViewMode.List;
            picker.FileTypeFilter.Add(".jpg");

            picker.PickSingleFileAndContinue();
        });
    }

    public void ContinueFileOpenPicker(FileOpenPickerContinuationEventArgs args)
    {
        // The "args" object contains information about selected file(s).
        if (args.Files.Any())
        {
            var file = args.Files[0];
            PhotoPath = file.Path;
        }
        else
        {
            PhotoPath = null;
        }
    }
}

The SelectPhotoCommand (lines 19-33) calls the FileOpenPicker.PickSingleFileAndContinue method, that opens a page allowing the selection of a file (a JPG image, in this case). Thanks to the ContinuationManager, as the ViewModel implements the IFileOpenPickerContinuable interface, the ContinueFileOpenPicker method will be automatically invoked when the user selects a file. We retrieve the first one and save its Path property, so we can show it, for example, in an Image control that is bound to it.

You can download a working example of the ContinuationManger with MVVM using the link below:

Using AndContinue methods in Windows Phone Store apps with MVVM

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