On Silverlight/Windows Phone, the FluidMoveBehavior can be used to animate the items of a ListBox when user adds or removes an item. But the behavior has no effect when the items are loaded and bound to the Listbox.

Imagine the following C# code corresponding to our ViewModel:

private ObservableCollection<Category> _categories;

public ObservableCollection<Category> Categories
{
    get
    {
        return this._categories;
    }
    set
    {
        this.Set(() => this.Categories, ref this._categories, value);
    }
}

public override async Task OnNavigatedTo(NavigationEventArgs navigationEventArgs, NavigationContext navigationContext)
{
    this.IsBusy = true;

    if (App.Categories == null)
    {
        App.Categories = await ClientServices.ClientServicesLocator.CategoriesService.GetAllCategoriesAsync();
    }

    this.Categories = new ObservableCollection<Category>(App.Categories);

    this.IsBusy = false;
}

And the associated XAML code:

<ListBox x:Name="CategoriesListBox" ItemsSource="{Binding Categories}">
    <ListBox.ItemTemplate>
        <DataTemplate>
            <TextBlock Text="{Binding Name}"
                       Style="{StaticResource PhoneTextTitle2Style}"
                       FontSize="40"
                       controls:TiltEffect.IsTiltEnabled="True"
                       x:Name="CategoryNameTextBlock" />
        </DataTemplate>
    </ListBox.ItemTemplate>
    <ListBox.ItemsPanel>
        <ItemsPanelTemplate>
            <StackPanel Orientation="Vertical" />
        </ItemsPanelTemplate>
    </ListBox.ItemsPanel>
</ListBox>

If you apply the FluidMoveBehavior to the StackPanel of the ListBox and go to the page, you’ll see that the items are all loaded on the same time, with no effect.

To change this, we can replace the ViewModel code with this one:

public Action RefreshCategories { get; set; }

public override async Task OnNavigatedTo(NavigationEventArgs navigationEventArgs, NavigationContext navigationContext)
{
    this.IsBusy = true;

    if (App.Categories == null)
    {
        App.Categories = await ClientServices.ClientServicesLocator.CategoriesService.GetAllCategoriesAsync();
    }

    this.RefreshCategories();
}

As you can see, we no longer use a property of the ViewModel to bind it to the view: we just have an Action property that is raised once the data are loaded. In the code-behind of the page, here is how we use the Action property:

public CategoriesPage()
{
    InitializeComponent();

    this._viewModel = this.DataContext as CategoriesPageViewModel;
    if (this._viewModel != null)
    {
        this._viewModel.RefreshCategories = async () =>
        {
            this.CategoriesListBox.Items.Clear();

            foreach (var category in App.Categories)
            {
                this.CategoriesListBox.Items.Add(category);

                await Task.Delay(100);
            }

            this._viewModel.IsBusy = false;
        };
    }
}

So once the action is raised, we first starts by clearing the items on the ListBox then, for each items we want to add, we add it to the Items property of the control. Then, we make a small pause using Task.Delay, to give some time to the UI to be refreshed!

To get a more clean result, it’s also possible to modify the DataTemplate:

<DataTemplate>
    <TextBlock Text="{Binding Name}"
               Style="{StaticResource PhoneTextTitle2Style}"
               FontSize="40"
               controls:TiltEffect.IsTiltEnabled="True"
               x:Name="CategoryNameTextBlock">
        <TextBlock.Resources>
            <EventTrigger x:Name="LoadEventTrigger"
                          RoutedEvent="Canvas.Loaded">
                <BeginStoryboard>
                    <Storyboard x:Name="FadeIn">
                        <DoubleAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.Opacity)"
                                                       Storyboard.TargetName="CategoryNameTextBlock">
                            <EasingDoubleKeyFrame KeyTime="0" Value="0.01"/>
                            <EasingDoubleKeyFrame KeyTime="0:0:0.5" Value="1"/>
                        </DoubleAnimationUsingKeyFrames>
                    </Storyboard>
                </BeginStoryboard>
            </EventTrigger>
        </TextBlock.Resources>
    </TextBlock>
</DataTemplate>

When the item is loaded, an animation is raised to change its opacity from 0 to 1. The result of the code can be seen on the first page of the following video (the animation on the second page will be covered in another post):

 

Happy coding!

Recently, I started to work on a Windows Phone application with all the data available through a Website (thanks to HtmlAgilityPack for helping me to parse the webpages).

All the parsing was quite easy but when I wanted to implement the search feature, I wondered how I could do this without any API ? Then, I discovered that the website was using a search form to propose the feature to its users so that was the way !

Here is the HTML code corresponding to the search form on the website:

<form method="post" action="http://www.mysyperwebsite.com/results.html">
    <input type="text" name="keyword" size="25" value="Enter some text..." onfocus="if (this.value=='Enter some text...') {this.value=''}" class="champs">&nbsp;
    <input type="button" onclick="ValidateSearch(this.form)" value="Search" alt="Search">
</form>

As we can see, the form send its data to the URL http://www.mysuperwebsite.com/results.html using the POST method. And that’s all we need to know! Indeed, we’ll do the same thing in our application: we’ll send a POST request to the indicated URL.

For that, we’ll use the HttpClient API and its PostAsync method (you can use the portable version of the HttpClient if you want). The PostAsync method takes in parameters the URI where to post the data and the content to send/post:

image

 

As we mimic the behavior of the form which post content, we’ll use the FormUrlEncodedContent object. This one takes in parameters a list of KeyValuePair, corresponding to the parameters sent by the search form:

var searchParameters = new List<KeyValuePair<string, string>> { new KeyValuePair<string, string>("keyword", searchText) };

Here is the complete code:

var searchUri = "http://www.mysuperwebsite.com/results.html";
var searchParameters = new List<KeyValuePair<string, string>> { new KeyValuePair<string, string>("keyword", searchText) };

using (var httpclient = new HttpClient())
{
    using (var content = new FormUrlEncodedContent(searchParameters))
    {
        using (var responseMessages = await httpclient.PostAsync(new Uri(searchUri, UriKind.Absolute), content))
        {
            return await responseMessages.Content.ReadAsStringAsync();
        }
    }
}

And voilà! Now, if you execute this code, it will be the same as if user use the search form.

 

Happy coding (and new year) ! :)

Today, we are going to see a small but useful tip for those who want to prevent a screen to turn off while there is no user activity.

This might be useful, for example, if there are some videos playing on your app: while the video are playing, the user does not interact with the app thus, depending to your power settings, the screensaver can start or the screen can even turn off!

To prevent this case, Microsoft offers the DisplayRequest API. The usage is really simple:

private DisplayRequest _displayRequest;

public void PreventDisplayToTurnOff()
{
    if(_displayRequest == null)
        _displayRequest = new DisplayRequest();

    _displayRequest.RequestActive();
}

public void AllowDisplayToTurnOff()
{
    if (_displayRequest == null)
        _displayRequest = new DisplayRequest();

    _displayRequest.RequestRelease();
}

Even if the usage is really simple, be careful of the following:

  • Use DisplayRequest API only when it’s necessary. Indeed, preventing the screen to start screensaver or to turn off impact battery life!
  • Don’t forget to release each request as soon as possible

Here is a simple helper that, I hope, will help you (this one might not be totally proper but, at least, it works on my case :)):

public class DisplayRequestHelper : IDisposable
{
    private bool _requestActivated;
    private DisplayRequest _displayRequest;

    public void PreventDisplayToTurnOff()
    {
        if (!_requestActivated)
        {
            if (_displayRequest == null)
                _displayRequest = new DisplayRequest();

            _requestActivated = true;
            _displayRequest.RequestActive();
        }
        else
        {
            throw new InvalidOperationException("An active request is already pending.");
        }
    }

    public void AllowDisplayToTurnOff()
    {
        if (_requestActivated)
        {
            if (_displayRequest == null)
                _displayRequest = new DisplayRequest();

            _requestActivated = false;
            _displayRequest.RequestRelease();
        }
        else
        {
            throw new InvalidOperationException("No active request found to be released.");
        }
    }

    public void Dispose()
    {
        try
        {
            if (_displayRequest != null)
            {
                _displayRequest.RequestRelease();
            }
        }
        finally
        {
            _requestActivated = false;
            _displayRequest = null;
        }
    }
}

To use it, just use the Dispose pattern:

using (var helper = new DisplayRequestHelper())
{
    helper.PreventDisplayToTurnOff();
}

This way, you’re sure that the active request are release as soon as possible!

 

Happy coding!

Most of the apps available are used by single users but imagine you want to develop an application that will allow users to switch user accounts. This lead us to, at least, 2 majors issues: how to store the credentials of the users ? How to allow them to easily switch the current user account ?

 

Storing user credentials:

Credential Locker, available through the PaswwordVault class, allows you to add, get or delete credentials for user in a secure way (all passwords are encrypted and cannot be accessed by other users). Other good point: the credentials are roamed with the Microsoft account users will be able to retrieved its credentials from another device without no cost!

To use the PasswordVault, it’s pretty simple:

private void AddCredentials(string userName, string password)
{
    var passwordVault = new Windows.Security.Credentials.PasswordVault();
    passwordVault.Add(new PasswordCredential(AppName, userName, password));
}

private bool CheckCredentials(string userName, string password)
{
    var retVal = false;

    var passwordVault = new Windows.Security.Credentials.PasswordVault();

    try
    {
        var passwordCredential = passwordVault.Retrieve(AppName, userName);
        if (passwordCredential != null)
        {
            retVal = passwordCredential.Password == password;
        }
    }
    catch (Exception)
    {
        // If the passwordvault does not contains the credentials
        retVal = false;
    }

    return retVal;
}

Once added, the credentials can be viewed from the Credential Manager and we can confirmed that roaming is activated:

image

Ok so now that the credentials are saved and we know how we can retrieved them, let’s see how to display a

 

Switch user account:

The AccountsSettingsPane is a new class in Windows 8.1 that let you add the Accounts command to the Settings Flyout. This command is available, for example, on the native mail application:

image  image

To get the entry added to the SettingsPane, simply add the command to the SettingsPage:

image

Then, the AccountsSettingsPane pane is used like the SettingsPane. First, get a reference to the pane of the current view then, add an event handler to the CommandRequested event:

image

Finally, all the magic appears at the end where you add a provider account for your app and, for each credentials that to the app, you add a web account command (specifying which actions user will be able to take when he will select an account):

image

image

During my investigations, I found that Mike Taulty has posted a similar blog post with Azure Mobile Services (available here) where he gives more details about how to handle the deconnection/reconnection (so I’ll not give you more details here, just look at his post).

 

PS: Source code is available here.

 

Happy coding!

Windows Store Applications allows developers to provide search suggestions to users, so they can find quickly what they are looking for.

For example, you can provide search suggestions using a Web Services or you can even use local files for that. Here is a “naïve” way to do it:

SearchPane.GetForCurrentView().SuggestionsRequested += async (sender, eventArgs) =>
{
    var deferral = eventArgs.Request.GetDeferral();

    int countNumberOfFilesAdded = 0;

    var picturesFiles = await KnownFolders.PicturesLibrary.GetFilesAsync();
    foreach (var file in picturesFiles)
    {
        if (file.DisplayName.StartsWith(eventArgs.QueryText))
        {
            eventArgs.Request.SearchSuggestionCollection.AppendQuerySuggestion(file.DisplayName);

            countNumberOfFilesAdded++;

            if (countNumberOfFilesAdded == 5)
                break;
        }
    }

    deferral.Complete();
};

The previous code woks fine and search for the files in the Pictures library to provide suggestions. But this code caan be easily replace using the LocalContentSuggestionSettings API:

var settings = new LocalContentSuggestionSettings();
settings.Enabled = true;
settings.Locations.Add(KnownFolders.PicturesLibrary);
settings.AqsFilter = "ext:jpg";

SearchPane.GetForCurrentView().SetLocalContentSuggestionSettings(settings);

Result is strictly the same: the content of the Pictures library is used to provide search suggestions:

  1. Sub-folders are include in the search
  2. You can easily customize the filter using an Advanced Query Syntax (AQS) filter
  3. You can search in all the locations you want (the Locations property is a list of StorageFolder)
  4. Code is more easier!

 

Happy coding!

[Windows 8] How to launch an app using NFC tags?

May 6th, 2013 | Posted by Tom in .NET | Article | Windows 8 | WinRT - (0 Comments) | Read: 6,484

Here is a quick (but quite useful) tip for anyone who want to use NFC tags on its application.

NFC tags can be used on Windows (Phone) to open Internet links but they can also be used to open a particular application on your system.

For that, you just need to use/create a LaunchApp message that will be written on the tag:

var proximityDevice = Windows.Networking.Proximity.ProximityDevice.getDefault();
if (proximityDevice) {
    proximityDevice.ondevicearrived = function(device) {
        var launchArgs = "user=Thomas LEBRUN";

        // Package.manifest -> View XML Source -> <Application Id="...">
        var appId = "App";

        var appName = Windows.ApplicationModel.Package.current.id.familyName + "!" + appId;

        var launchAppArgs = launchArgs + "\tWindows\t" + appName;

        var dataWriter = new Windows.Storage.Streams.DataWriter();
        dataWriter.unicodeEncoding = Windows.Storage.Streams.UnicodeEncoding.utf16LE;
        dataWriter.writeString(launchAppArgs);

        var launchAppId = proximityDevice.publishBinaryMessage("LaunchApp:WriteTag", dataWriter.detachBuffer());
       proximityDevice.stopPublishingMessage(launchAppId);
   };
}

The content of the tag is a string, where all the items are separated by “\t”:

  1. Some arguments that you want to use when the app starts
  2. The plateform (in our case, we need to specify “Windows”)
  3. The application name, which contains:
    1. The application id (this one can be found in the manifest file, under the attribute Id of the tag Application)
    2. The current package family name

Using this parameters, we can publish a particular message: LaunchApp:WriteTag. This tag/message will be recognize by the platform which will then ask for the user to open the dedicated application.

So you can easily imagine use this technique to create an new kind of authentification in your application (at least to provide the username).

 

Happy coding!

Scrolling in Windows Store applications is mostly done in horizontal mode. This is something quite easy to do with the GridView which support scrolling with mouse wheel but this can be a quite more complicated to do in Webview.

Indeed, in the Webview control, the mouse wheel scroll is done in vertical mode so here is a quick fix to perform the same scroll in horizontal mode.

To do this, you can use a JQuery plugin like JQuery.MouseWheel: https://github.com/brandonaaron/jquery-mousewheel

In your Webview, load JQuery and this plugin:

var scriptJQuery = "<script type='text/javascript' src='http://code.jquery.com/jquery-1.7.js'></script>";
var scriptJQueryMouseWheel = "<script type='text/javascript' src='ms-appx-web:///Views/web/jquery.mousewheel.js'></script>";

var content = "<!doctype html><html lang=\"fr\"><head><link rel=\"stylesheet\" href=\"ms-appx-web:///Views/web/web.css\" type=\"text/css\" media=\"screen\" />" scriptJQuery + scriptJQueryMouseWheel + "</head>" +
    "<div id=\"articleContent\"><font id=\"article\" face=\"Segoe UI\">" +
        SelectedNews.Description +
    "</div></font>" +
"</html>";

webView.NavigateToString(content);

Once this is done, we can just add a small JavaScript function to handle the “MouseWheel” event:

var mouseWheelScript = "<script type=\"text/javascript\">" +
                        "$(function() {" +
                            "$('html, body').mousewheel(function(event, delta) {" +
                                "this.scrollLeft -= (delta * 50);" +
                                "event.preventDefault();" +
                            "});" +
                        "});" +
                    "</script>";

So the complete code is the following one:

var scriptJQuery = "<script type='text/javascript' src='http://code.jquery.com/jquery-1.7.js'></script>";
var scriptJQueryMouseWheel = "<script type='text/javascript' src='ms-appx-web:///Views/web/jquery.mousewheel.js'></script>";

var mouseWheelScript = "<script type=\"text/javascript\">" +
                        "$(function() {" +
                            "$('html, body').mousewheel(function(event, delta) {" +
                                "this.scrollLeft -= (delta * 50);" +
                                "event.preventDefault();" +
                            "});" +
                        "});" +
                    "</script>";

var content = "<!doctype html><html lang=\"fr\"><head><link rel=\"stylesheet\" href=\"ms-appx-web:///Views/web/web.css\" type=\"text/css\" media=\"screen\" />" + scriptResize + scriptVideo + scriptJQuery + scriptJQueryMouseWheel + mouseWheelScript + "</head>" +
    "<div id=\"articleContent\"><font id=\"article\" face=\"Segoe UI\">" +
        SelectedNews.Description +
    "</div></font>" +
"</html>";

webView.NavigateToString(content);

Now, each time the Webview will get the focus, user will be able to perform a horizontal scrolling using the mousewheel.

Pretty simple when you know!

Please note that the plugin’s file is loaded from ms-appx-web to allow Webview to load it correctly.

 

Happy coding!

Here is a problem we met recently with my colleague Jonathan.

Indeed, in one of the Windows 8 applications we are working, we have a Webview that is loaded thanks to the method NavigateToString:

WebviewNews.NavigateToString(content);

(where content is the HTML fragment that will be displayed in the Webview).

On that HTML, we wanted to insert a custom CSS file so we tried the following:

 var content =
    "<html><head><link rel=\"stylesheet\" href=\"ms-appx:///Views/web/web.css\" type=\"text/css\" media=\"screen\" /></head>" +
         "<font face=\"Segoe UI\">" +
             NewsDetailPageViewModel.SelectedNews.Description +
         "</font>" +
     "</html>";
 WebviewNews.NavigateToString(content);

Unfortunately, this does not work: the code is correct but the CSS rules were not applied.

After a quick look, it appears that the fix is simple: instead of using ms-appx, we needed to use ms-appx-web. Content referenced via this scheme is loaded from the local package, but runs with the abilities and restrictions of the web context.

The correct code was:

 var content =
    "<html><head><link rel=\"stylesheet\" href=\"ms-appx-web:///Views/web/web.css\" type=\"text/css\" media=\"screen\" /></head>" +
         "<font face=\"Segoe UI\">" +
             NewsDetailPageViewModel.SelectedNews.Description +
         "</font>" +
     "</html>";
 WebviewNews.NavigateToString(content);

Using this syntax, the CSS rules were correctly loaded and the HTML content was correctly modified according to our CSS rules.

 

Happy coding!

I’m glad to announce that my first MSDN article (Building and Validating Windows Store Apps with Team Foundation Service) is now available !

It’s a topic I’ve already covered on my blog but I hope you’ll get more information and details in the new and revisited version!

The article is available here: http://msdn.microsoft.com/en-us/magazine/dn166931.aspx

Happy coding (and building) !

A small tip for anyone who look for the information.

Using a custom font in any Windows Store apps (C# / XAML) is easy and the same as you can do in WPF or Silverlight application.

Indeed, the first step is to add the font file to your solution and mark it as “Content” (on the file’s properties). Then, when you want to use your new font, just set the FontFamily property:

 <TextBlock Text="u"
                    FontSize="72"
                    Foreground="Red"
                    FontFamily="Assets/MyNewFont.ttf#My Font Name"/>

As you can see, you just need to point to the right file and add the font name after the # character (this is because a single file can contains multiple fonts so using this syntax, you know exactly which font will be used).

Note that Visual Studio and Expression Blend both support the feature so you’ll be able to see the change directly in the designers.

 

Happy coding!