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) !

Windows 8 provide a new Transcoding API that can help you to transcode an audio or video file from one format to another one.

The API is really simple to use and consist of two majors classes:

  1. MediaEncodingProfile, which contains the settings that will determine how the destination file will be transcoded
  2. MediaTranscoder, which will perform the transformation

First, you need to create a profile to indicate how to transcode the file:

var encodingProfile = MediaEncodingProfile.CreateMp4(VideoEncodingQuality.HD1080p);

MediaEncodingProfile contains factory methods like CreateMp4 or CreateWmv. The parameter of the methods gives the target resolution (in our case 1080p).

Next, you can call PrepareFileTranscodeAsync to transcode the file (after checking if the source can really be transcoded):

var prepareTranscodeResult = await transcoder.PrepareFileTranscodeAsync(sourceFile, destinationFile, encodingProfile);

if (prepareTranscodeResult.CanTranscode)
{
    await prepareTranscodeResult.TranscodeAsync();
}

And voila! Again, you can see that the API is very simple and flexible (you can, if you want, load a profile from a file or trim the destination file using the properties TrimStartTime and TrimStopTime!).

For my tests, I’ve worked with a WMV file of 30 seconds for 25Mb. After converted it in MP4 (1080p), the result file was 65Mb (more bigger for more quality) and another conversion to VGA gave a file of 11Mb: as you can see, the result file depend of the quality you decide to use.

So now, you’re ready to create you own audio/video editor in a cool Windows Store app!

 

Happy coding!

Windows Azure Mobile Services is a awesome product that will help you to deliver great apps using a Windows Azure backend.

One of the feature I like is the possibility to send push notifications to modify tiles in just few lines of code. There is just a small drawback to this technique: as the queue notification must be enable from the client code, you won’t be able to get animated tiles.

But (as there is always a “but” ;), the next part of this post will provide you a simple but useful technique to get animated tiles for you Windows Store app.

In fact, instead of of send a classic notification, we’ll use the sendRaw method of the wns object to send a Raw notification. As a reminder, a raw notification is a notification that’s not displayed on the screen: as a developer, your code is notified that the notification is coming and you have to perform what you want/need.

So first, you have to create your server script (here is mine as an example):

var LASTEST_QUOTES_NUMBER = 5;

var payload;
var idx;

function cleanChannels(callback) {
    var channelsTable  = tables.getTable('Channel');

    channelsTable.read({
        success: function(channels) {
            if(channels.length > 0) {
                channels.forEach(function(channel){
                    if(channel.expirationTime < new Date()){
                        channelsTable.del(channel.id);
                    }
                })
            }

            if(callback) {
                callback();
            }
        }
    })
}

function preparePayload(movie, quote){
     payload += "<QuoteWithMovie>" +
                    "<Movie Title=\"" + movie.title + "\" FrontCover=\"" + movie.poster_path + "\" BackCover=\"" + movie.backdrop_path + "\" />" +
                    "<Quote Text=\"" + quote.text.substring(100) + "\" />" +
                "</QuoteWithMovie>";

    idx++;

    if(idx == LASTEST_QUOTES_NUMBER) {

        payload += "</Results>";

        cleanChannels(function() {
            var channelsTable  = tables.getTable('Channel');

            channelsTable.read({
                success: function(channels) {
                    if(channels.length > 0) {
                        for (var i = 0; i < channels.length; i++) {
                            var channel = channels[i];

                            push.wns.sendRaw(channel.uri, payload);
                        }
                    }
                }
            });
        });
    }
}

function sendLatestQuotes() {

    payload = "";
    idx = 0;

    var moviesTable = tables.getTable('Movie');
    var quotesTable = tables.getTable('Quote');

    quotesTable.where({ ispublished: true })
    .orderBy('date')
    .take(LASTEST_QUOTES_NUMBER)
    .read({
        success: function(latestQuotes) {
            payload += "<Results>";

            latestQuotes.forEach(function(quote) {
                moviesTable.where({ movieid: quote.movieid })
                .read({
                    success: function(movies) {
                       preparePayload(movies[0], quote);
                    }
                })
            })
        }
    })
}

As you can see, the code is pretty simple: a XML payload is construct from some database records and, when I have the number of notification I want (5 because notification queuing allow you to switch up to 5 notifications), I send a raw notification, using the payload constructed before.

On the client side, the code use the PushNotificationReceived event to be notified and, if a raw notification is coming, the code use the content (the XML payload) to update the tile:

 var currentChannel = await PushNotificationChannelManager.CreatePushNotificationChannelForApplicationAsync();
currentChannel.PushNotificationReceived += async (sender, args) =>
{
    if (args.NotificationType == PushNotificationType.Raw && args.RawNotification != null)
    {
        await MainTileUpdateTask.UpdateMainTileAsync(args.RawNotification.Content);

        // The raw notification should not be passed to its background task
        args.Cancel = true;
    }
};

The code to update the tile and animate it is dedicated to your application but, for you records, here is the one I’m using:

internal static async Task UpdateMainTile(string content)
{
    _isUpdatingTile = true;

    var tileUpdater = TileUpdateManager.CreateTileUpdaterForApplication();
    tileUpdater.EnableNotificationQueue(true);

    tileUpdater.Clear();

    var xElement = XElement.Parse(content);
    var quotesWithMovies = from q in xElement.Elements("QuoteWithMovie")
                                            let movie = q.Element("Movie")
                                            let quote = q.Element("Quote")
                                            select new QuoteWithMovie
                                            {
                                                  MovieTitle = movie.Attribute("Title").Value,
                                                  FrontCover = movie.Attribute("FrontCover").Value,
                                                  BackCover = movie.Attribute("BackCover").Value,
                                                  Text = quote.Attribute("Text").Value
                                            };

    var quoteWithMovies = quotesWithMovies as IList<QuoteWithMovie> ?? quotesWithMovies.ToList();
    if (quoteWithMovies.Any())
    {
        for (int index = 0; index < quoteWithMovies.Count; index++)
        {
            var quote = quoteWithMovies[index];

            var frontCoverFileFullUrl =
            await MoviesService.Current.GetFullCoverImageUrlAsync(quote.FrontCover, "w154");
            var backCoverFileFullUrl =
            await MoviesService.Current.GetFullCoverImageUrlAsync(quote.BackCover, "w300");

            var squareImageFilename = string.Format("Square_{0}.jpg", index);
            var wideImageFilename = string.Format("Wide_{0}.jpg", index);

            FileHelpers.DownloadFile(ApplicationData.Current.LocalFolder, squareImageFilename,
            frontCoverFileFullUrl);

            FileHelpers.DownloadFile(ApplicationData.Current.LocalFolder, wideImageFilename,
            backCoverFileFullUrl);

            var wideTile = Core.UI.Notifications.TileContentFactory.CreateTileWideImageAndText01();
            wideTile.Branding = TileBranding.None;
            wideTile.RequireSquareContent = false;
            wideTile.Image.Src = string.Format("ms-appdata:///local/{0}", wideImageFilename);
            wideTile.Image.Alt = quote.MovieTitle;
            wideTile.TextCaptionWrap.Text = quote.Text;

            var squareTile = Core.UI.Notifications.TileContentFactory.CreateTileSquareImage();
            squareTile.Branding = TileBranding.None;
            squareTile.Image.Src = string.Format("ms-appdata:///local/{0}", squareImageFilename);
            squareTile.Image.Alt = quote.MovieTitle;

            var wideTileNotification = wideTile.CreateNotification();
            var squareTileNotification = squareTile.CreateNotification();

             tileUpdater.Update(wideTileNotification);
             tileUpdater.Update(squareTileNotification);
         }
    }

    _isUpdatingTile = false;
}

The might be others techniques to perform the same results but I like this one for one reason: raw notification can be received by BackgroundTask!

So if you add a BackgroundTask (which set its trigger to PushNotificationTrigger) and put you server code in a Mobile Services Scheduler, you’ll be able to update the tile even if the app is not running!

 

Happy coding!

Indeed, there are no Size or Length properties exposed by the StorageFile class. So a simple but useful trick is to read the content of the file as a Buffer and access to the Length property to access the basic properties of the file and use the Size property:

public async static Task<ulong> GetFileSizeAsync(this IStorageFile file)
{
    var properties = await file.GetBasicPropertiesAsync();

    return properties.Size;
}

Happy coding !

If you’ve never tried TFS Service yet, you might give it a try right now. Indeed, based on Team Foundation Server 2012, it provides to developers source control feature, build, test and more!

The Build service is really cool because you’ll be able to build any kind of applications and, because it’s cloud-based, you won’t need to have your server running by yourself!

But, even if it’s cool, Build service on TFS Service is still in preview and so, there might be some issues. The first one is that you can’t build Windows Store apps. Indeed, if you try, you’ll encountered the following error:

image

At least, this is a very clear message. Fortunately, as it’s based on TFS 2012, we’ll be able to add a new Build Controller/Agent to indicate to TFS Service that we want to build Windows Store apps on a particular machine (one with Windows 8).

So, first step is to create a Windows 8 virtual machine (I won’t detailed this procedure here as it’s easy to do). Once the VM is ready, we can install all the stuff that we might need: Visual Studio 2012, Windows SDK, etc. (I know that installing VS on build machine might not be the proper way to do but, at least, it works every time).

Once the machine is ready, we’ll add a new build controller and build agent on it. For that, start the installation of Team Foundation Server 2012:

image

Once the installation is done, the Configuration Center is displayed on screen. Here, we won’t choose to configure Team Foundation Application Server but only the Team Foundation Build Service so select this entry and click on “Start Wizard”:

image

On the next screen that appears, you are asking to select the Team Project collection you are configuring build services for:

image

So click on the “Browse” button and add your TFS Service server:

image

Once authenticated, you can select the Team Project Collection that you want:

image

Then, you’ll be back to the previous screen, with the information dedicated to the build services for your team project collection (if you just start, you may see the same thing as the screenshot below: 0 build controller(s) and 0 build agent(s) because even if there are already a build controller/agent for TFS Service, they are is idle state until you trigger a new build):

image

Next, you are ask to configure the number of build controller(s)/agent(s) you want to install on the machine. For now, we’ll just install the build service so choose to configure later (we’ll do it after):

image

Please, note that the number of build agent(s) recommended is proposed according by your server specs (as build agents run concurrently and do processor-intensive work).

Next, you need to provide the account that will run the Build Service. You can use one of the system account but I’m not a big fan of this possibility. I prefer to create dedicated account (but feel free to do as you want for this part):

image

Once the readiness checks has been validated, you’re ready to configure the Build Service:

image

image

Once finish, click on “Close”:

image

You can now see that the Build Service is installed and configured:

image

Now that the service is installed, it’s time to add a controller and an agent. Launch the Team Foundation Server Administration Console from the Start Menu:

image

From the console, select “Build Configuration” to see that the Build Service is configured for the Team Project Collection you’ve chosen and that there is no controller(s)/agent(s):

image

Now, we’ll add a new controller to the Build Service. Why this is needed ? Because you cannot add/attach an on-premise build agent to a hosted build controller (the one available in TFS Service):

image

So click on the “New Controller…” link and add a new one:

image

Once the controller is up & running, we are now ready to add an agent on it so click on the link “New Agent…”:

image

Be sure to select the controller that you’ve just created otherwise, you’ll encountered the previous error. Also, note that I’ve added a tag. This is not necessary but when I’ll create the build definition (later), it’ll help to to be sure that only this agent will be used because this is the only one able to build Windows 8 apps

image

Now that controller and agent are ready, it’s the moment to create the Build definition that will use them to build Windows 8 apps:

image

In Visual Studio, open the Team Explorer, select “Builds” and, under “Actions”, click on “Manage Build Controllers…”:

image

The screen that appears display the list of all controllers/agents available for the Team Project Collection and, as you can see, the controller and agent we have created are correctly displayed (marked as Available):

image

Now, click on the link “New Build Definition” and fill the information needed (I won’t detailed all the screens as they are simples). the most important part is the “Build Defaults” where you have to select the controller we have installed previously and the path where the build outputs will be sent:

image

One the next screen (“Process”), choose the items to build but, most important (under Advanded –> Agent Settings), select the tag corresponding to the agents you want to use to perform this build:

image

image

Save the build definition then start a new build:

image

And voila ! :)

image

The build has been executed successfully and, if you look in the output/drop folder, you’ll see that the package has been deployed correctly:

image

 

Bonus:

Now that your build service is able to build Windows Store apps, you can keep your Virtual Machine on your own DataCenter or, thanks to Windows Azure Virtual Machine, you can upload it in Windows Azure to use it from here. The task to upload a VHD in Windows Azure is really well described here http://www.windowsazure.com/en-us/manage/windows/common-tasks/upload-a-vhd/ or here http://msdn.microsoft.com/en-us/library/windowsazure/gg465385.aspx

Once uploaded (be careful, it can take a very long time according to the VM size), follow the following steps to create a Virtual Machine from VHD (in Windows Azure): http://www.cloudtec.ch/blog/tech/create-virtual-machine-vhd-in-azure.html

 

Now, you don’t have any excuse to not have a real continuous integration for you Windows Store apps!

 

Happy building!

ASP.NET SignalR is a project developed by Microsoft to allow developers to add real-time web functionality to your applications. Here is the official description of the project:

ASP.NET SignalR is a new library for ASP.NET developers that makes it incredibly simple to add real-time web functionality to your applications. What is “real-time web” functionality? It’s the ability to have your server-side code push content to the connected clients as it happens, in real-time.

You may have heard of WebSockets, a new HTML5 API that enables bi-directional communication between the browser and server. SignalR will use WebSockets under the covers when it’s available, and gracefully fallback to other techniques and technologies when it isn’t, while your application code stays the same.

SignalR also provides a very simple, high-level API for doing server to client RPC (call JavaScript functions in your clients’ browsers from server-side .NET code) in your ASP.NET application, as well as adding useful hooks for connection management, e.g. connect/disconnect events, grouping connections, authorization.

So as soon as you plan to push content from your server to one (of more) of clients, you might take a look at SignalR. I’ve started to play with it this week (a good way to start the new year) and so, here is a brief introduction to this (and powerful) framework!

First, on the server side, you have to add a reference to the correct Nuget package (be careful, the project is not in the stable branch yet):

image

Then, you have to create a Hub, in other words a kind of endpoint that will expose the methods to all the clients. Defining a hub just mean create a class that derive from the Hub class:

public class DemoHub : Hub
{
    public void Send(string message)
    {
        Clients.All.getMessage(message);
    }

    public string SayHello(string name)
    {
        return "Hello" + name;
    }
}

Deriving from the Hub class allows you to access to the Clients property which can be used to access:

  1. To all the clients connected (through the All property),
  2. To the caller of the method (through the Caller property),
  3. Etc

image

Once that you get access to the list of clients you want, you can call the methods that you want on that clients (here, on our code, we call the getMessage of each clients, passing in parameter needed):

public void Send(string message)
{
    Clients.All.getMessage(message);
}

Of course, you can also defined some methods that will be called by the clients:

public string SayHello(string name)
{
    return "Hello" + name;
}

Now that the server part is done, we can start the client part. SignalR have Nuget packages for most of the client API: .NET, Windows Phone, WinRT, Silverlight and even Javascript: this is very powerful !

First, we need to create a connection to the Web Server:

var connection = new HubConnection("http://localhost:49449/");

Once this is done, we can create a proxy that will allow us to invoke methods on the server (and being notified when the server call a method on the clients): it’s the same job as the WCF proxy created when you add a service reference (except that this new one is not strongly typed):

var proxy = connection.CreateHubProxy("DemoHub");

You can see that the CreateHubProxy method takes in parameter the class name of the Hub you’ve created on the Web Server. If you want, you can use the HubName attribute (on the Hub class) to get a kind of alias for your hub:

[HubName("MyHubTest")]
public class DemoHub : Hub

In that case, the method CreateHubProxy will look like:

// Create a proxy to the service
var proxy = connection.CreateHubProxy("MyHubTest");

Next, you have to perform 2 things:

  1. Add a kid of event handler to all the methods that will be called by the server of the clients
  2. Start the connection

If the second one is really simple (just call the Start method of the HubConnection type), the first one is simple too. Indeed, on the proxy you’ve created, you can use the extension method On, that takes in parameters:

  1. The name of the “event” you want to be notified
  2. An Action (and its parameters) corresponding to the parameters sent from the server

image

So, in our case, if we want to be notified when the method getMessage is called from the server, we just need to use the following code:

proxy.On("getMessage", message =>
{
    this.Dispatcher.RunAsync(CoreDispatcherPriority.Normal, () => lb.Items.Add(message));
});

// Start the connection
await connection.Start();

Pretty simple!

Lastly, we need to be able to invoke the methods defined on the Hub so we’ll use the method Invoke of the proxy:

// Call the method on the server
await proxy.Invoke("Send", "My name is WinRT");

// Call the method on the server and get the result
var s = await proxy.Invoke<string>("SayHello", "Tom");

Now, let’s use the same code from an application console:

// Connect to the service
var connection = new HubConnection("http://localhost:49449/");

// Create a proxy to the service
var proxy = connection.CreateHubProxy("DemoHub");

// Start the connection
await connection.Start();

// Call the method on the server
await proxy.Invoke("Send", "My name is Console");

(As you can see, the code is strictly the same !)

If we launch the application from the Windows 8 side (the one where the handler to getMessage has been set), we can see that all the messages has been sent to the server and broadcast to the clients:

image

So, as you can see, getting push system in any kind of applications is pretty easy using SignalR. If you want to get more info, you can take a look at the Wiki. Also, don’t hesitate to go to David Fowler’s blog, the main developer of the project.

 

Happy coding!

In Windows Store applications, the Settings contract offers to developers the possibility to add link to the Charms bar, under the Settings part:

The Settings are simple links to some page that will be display in the Settings flyout when the user will click on it:

app.onsettings = function (args) {
       var settings =
       {
           "About":
           {
               title: "About",
               href: "/Pages/otherPages/aboutPage.html"
           }
       };

       args.detail.applicationcommands = settings;

       WinJS.UI.SettingsFlyout.populateSettings(args);
};

This is great if you want to display a page from your application to the user but what happens if you just want to launch an Internet link when user click on one of your Settings link?

Well, as always, there is a code for that and this one is pretty simple: just add an event handler to the CommandRequested event of the SettingsPane and add your link directly within it:

function setupSettingsPane() {
        var settingsPane = Windows.UI.ApplicationSettings.SettingsPane.getForCurrentView();
        settingsPane.addEventListener("commandsrequested", function (eventArgs) {

        var launchBlogCommand = new Windows.UI.ApplicationSettings.SettingsCommand("LaunchBlogCmd", "My Blog", function () {
            var uri = new Windows.Foundation.Uri("http://blog.thomaslebrun.net);

            Windows.System.Launcher.launchUriAsync(uri);
        });

        eventArgs.request.applicationCommands.append(launchBlogCommand);
    });
};

(Note that even if the code provided here is in JavaScript, the same results can be achieved using C# !)

 

Happy coding!

One of my co-worker wanted to have, in its application, a FlipView that can change automatically its content. Changing the SelectedIndex property is quite good but not enough because the change is hard and he wanted to have an animation when the item change.

After taking a look at the template of the FlipView, it appears that it’s just a ScrollViewer containing an ItemsPresenter. So basically, what I needed to do was to find a way to animate the HorizontalOffset property of the ScrollViewer. Unfortunately, you won’t be able to animate this property directly. But, as you’ll find here, there is a solution that consist of using a Mediator (thanks David Anson for the tip and your good posts on Silverlight !).

Finally, if you want to animate your custom Dependency Property, you’ll need to add if to the Visual Tree (as it’s confirmed here).

So now, let’s take a look at the code ! Here is the code behind of the control:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;
using Windows.UI.Xaml.Media.Animation;

namespace AnimatedFlipView
{
    public class AnimatedFlipView : FlipView
    {
        private ScrollViewer _scrollViewer;
        private ScrollViewerOffsetMediator _mediator;

        private bool _isRunningAnimation;
        private bool _reverseAnimation;

        public AnimatedFlipView()
        {
            DefaultStyleKey = typeof (AnimatedFlipView);

            this.Loaded += OnLoaded;
        }

        private void OnLoaded(object sender, RoutedEventArgs e)
        {
            if (this._scrollViewer != null && this._mediator != null)
            {
                var timer = new DispatcherTimer();
                timer.Interval = TimeSpan.FromSeconds(3);
                timer.Tick += (o, o1) =>
                {
                    if (!this._isRunningAnimation)
                    {
                        var sb = new Storyboard();

                        var nextItemAnimation = new DoubleAnimation
                        {
                            EnableDependentAnimation = true,
                            Duration = new Duration(TimeSpan.FromSeconds(2)),
                            From = this._scrollViewer.HorizontalOffset,
                            To = this._reverseAnimation ? this._scrollViewer.HorizontalOffset - 1 : this._scrollViewer.HorizontalOffset + 1,
                            FillBehavior = FillBehavior.HoldEnd,
                            EasingFunction = new ExponentialEase
                            {
                                EasingMode = EasingMode.EaseOut
                            }
                        };

                        Storyboard.SetTarget(nextItemAnimation, this._mediator);
                        Storyboard.SetTargetProperty(nextItemAnimation, "HorizontalOffset");

                        sb.Children.Add(nextItemAnimation);

                        sb.Completed += (sender1, o2) =>
                        {
                            if (this._reverseAnimation)
                            {
                                if (this.SelectedIndex > 0)
                                {
                                    this.SelectedIndex--;
                                }

                                if (this.SelectedIndex == 0)
                                {
                                    this._reverseAnimation = false;
                                }
                            }
                            else
                            {
                                if (this.Items != null && this.SelectedIndex < this.Items.Count - 1)
                                {
                                    this.SelectedIndex++;
                                }

                                if (this.Items != null && this.SelectedIndex == this.Items.Count - 1)
                                {
                                    this._reverseAnimation = true;
                                }
                            }

                            this._isRunningAnimation = false;
                        };

                        sb.Begin();

                        this._isRunningAnimation = true;
                    }
                };
                timer.Start();
            }
        }

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

            this._scrollViewer = this.GetTemplateChild("ScrollingHost") as ScrollViewer;
            this._mediator = this.GetTemplateChild("Mediator") as ScrollViewerOffsetMediator;
            if (this._scrollViewer == null || this._mediator == null)
            {
                throw new NullReferenceException("ScrollingHost and Mediator must not be null.");
            }

            this.SelectionChanged += OnSelectionChanged;
        }

        private void OnSelectionChanged(object sender, SelectionChangedEventArgs selectionChangedEventArgs)
        {
            this._scrollViewer.ScrollToHorizontalOffset(this._reverseAnimation
                                                                    ? (this._mediator.HorizontalOffset - 1)
                                                                    : (this._mediator.HorizontalOffset + 1));
        }
    }

    /// <summary>
    /// Mediator that forwards Offset property changes on to a ScrollViewer
    /// instance to enable the animation of Horizontal/VerticalOffset.
    /// </summary>
    public class ScrollViewerOffsetMediator : FrameworkElement
    {
        /// <summary>
        /// ScrollViewer instance to forward Offset changes on to.
        /// </summary>
        public ScrollViewer ScrollViewer
        {
            get { return (ScrollViewer)GetValue(ScrollViewerProperty); }
            set { SetValue(ScrollViewerProperty, value); }
        }
        public static readonly DependencyProperty ScrollViewerProperty =
            DependencyProperty.Register(
                "ScrollViewer",
                typeof(ScrollViewer),
                typeof(ScrollViewerOffsetMediator),
                new PropertyMetadata(null, OnScrollViewerChanged));
        private static void OnScrollViewerChanged(DependencyObject o, DependencyPropertyChangedEventArgs e)
        {
            var mediator = (ScrollViewerOffsetMediator)o;
            var scrollViewer = (ScrollViewer)(e.NewValue);
            if (null != scrollViewer)
            {
                scrollViewer.ScrollToVerticalOffset(mediator.VerticalOffset);
            }
        }

        /// <summary>
        /// VerticalOffset property to forward to the ScrollViewer.
        /// </summary>
        public double VerticalOffset
        {
            get { return (double)GetValue(VerticalOffsetProperty); }
            set { SetValue(VerticalOffsetProperty, value); }
        }
        public static readonly DependencyProperty VerticalOffsetProperty =
            DependencyProperty.Register(
                "VerticalOffset",
                typeof(double),
                typeof(ScrollViewerOffsetMediator),
                new PropertyMetadata(null, OnVerticalOffsetChanged));

        public static void OnVerticalOffsetChanged(DependencyObject o, DependencyPropertyChangedEventArgs e)
        {
            var mediator = (ScrollViewerOffsetMediator)o;
            if (null != mediator.ScrollViewer)
            {
                mediator.ScrollViewer.ScrollToVerticalOffset((double)(e.NewValue));
            }
        }
        /// <summary>
        /// Multiplier for ScrollableHeight property to forward to the ScrollViewer.
        /// </summary>
        /// <remarks>
        /// 0.0 means "scrolled to top"; 1.0 means "scrolled to bottom".
        /// </remarks>
        public double ScrollableHeightMultiplier
        {
            get { return (double)GetValue(ScrollableHeightMultiplierProperty); }
            set { SetValue(ScrollableHeightMultiplierProperty, value); }
        }

        public static readonly DependencyProperty ScrollableHeightMultiplierProperty =
            DependencyProperty.Register(
                "ScrollableHeightMultiplier",
                typeof(double),
                typeof(ScrollViewerOffsetMediator),
                new PropertyMetadata(null, OnScrollableHeightMultiplierChanged));

        public static void OnScrollableHeightMultiplierChanged(DependencyObject o, DependencyPropertyChangedEventArgs e)
        {
            var mediator = (ScrollViewerOffsetMediator)o;
            var scrollViewer = mediator.ScrollViewer;
            if (null != scrollViewer)
            {
                scrollViewer.ScrollToVerticalOffset((double)(e.NewValue) * scrollViewer.ScrollableHeight);
            }
        }

        /// <summary>
        /// HorizontalOffset property to forward to the ScrollViewer.
        /// </summary>
        public double HorizontalOffset
        {
            get { return (double)GetValue(HorizontalOffsetProperty); }
            set { SetValue(HorizontalOffsetProperty, value); }
        }
        public static readonly DependencyProperty HorizontalOffsetProperty =
            DependencyProperty.Register(
                "HorizontalOffset",
                typeof(double),
                typeof(ScrollViewerOffsetMediator),
                new PropertyMetadata(null, OnHorizontalOffsetChanged));

        public static void OnHorizontalOffsetChanged(DependencyObject o, DependencyPropertyChangedEventArgs e)
        {
            var mediator = (ScrollViewerOffsetMediator)o;
            if (null != mediator.ScrollViewer)
            {
                mediator.ScrollViewer.ScrollToHorizontalOffset((double)(e.NewValue));
            }
        }
        /// <summary>
        /// Multiplier for ScrollableWidth property to forward to the ScrollViewer.
        /// </summary>
        /// <remarks>
        /// 0.0 means "scrolled to left"; 1.0 means "scrolled to right".
        /// </remarks>
        public double ScrollableWidthMultiplier
        {
            get { return (double)GetValue(ScrollableWidthMultiplierProperty); }
            set { SetValue(ScrollableWidthMultiplierProperty, value); }
        }

        public static readonly DependencyProperty ScrollableWidthMultiplierProperty =
            DependencyProperty.Register(
                "ScrollableWidthMultiplier",
                typeof(double),
                typeof(ScrollViewerOffsetMediator),
                new PropertyMetadata(null, OnScrollableWidthMultiplierChanged));

        public static void OnScrollableWidthMultiplierChanged(DependencyObject o, DependencyPropertyChangedEventArgs e)
        {
            var mediator = (ScrollViewerOffsetMediator)o;
            var scrollViewer = mediator.ScrollViewer;
            if (null != scrollViewer)
            {
                scrollViewer.ScrollToHorizontalOffset((double)(e.NewValue) * scrollViewer.ScrollableWidth);
            }
        }
    }
}

And here is the template of the control (as you can see, it’s the same template of the FlipView except that I’ve included the ScroolViewerOffsetMediator):

<Style TargetType="animatedFlipView:AnimatedFlipView">
        <Setter Property="Background"
                Value="Transparent" />
        <Setter Property="BorderThickness"
                Value="0" />
        <Setter Property="TabNavigation"
                Value="Once" />
        <Setter Property="IsTabStop"
                Value="False" />
        <Setter Property="ScrollViewer.HorizontalScrollBarVisibility"
                Value="Hidden" />
        <Setter Property="ScrollViewer.VerticalScrollBarVisibility"
                Value="Hidden" />
        <Setter Property="ScrollViewer.IsHorizontalRailEnabled"
                Value="False" />
        <Setter Property="ScrollViewer.IsVerticalRailEnabled"
                Value="False" />
        <Setter Property="ScrollViewer.IsHorizontalScrollChainingEnabled"
                Value="True" />
        <Setter Property="ScrollViewer.IsVerticalScrollChainingEnabled"
                Value="True" />
        <Setter Property="ScrollViewer.IsDeferredScrollingEnabled"
                Value="False" />
        <Setter Property="ScrollViewer.BringIntoViewOnFocusChange"
                Value="True" />
        <Setter Property="ItemsPanel">
            <Setter.Value>
                <ItemsPanelTemplate>
                    <VirtualizingStackPanel AreScrollSnapPointsRegular="True"
                                            Orientation="Horizontal" />
                </ItemsPanelTemplate>
            </Setter.Value>
        </Setter>
        <Setter Property="Template">
            <Setter.Value>
                <ControlTemplate TargetType="animatedFlipView:AnimatedFlipView">
                    <Grid>
                        <VisualStateManager.VisualStateGroups>
                            <VisualStateGroup x:Name="FocusStates">
                                <VisualState x:Name="Focused">
                                    <Storyboard>
                                        <DoubleAnimation Storyboard.TargetName="FocusVisualWhite"
                                                         Storyboard.TargetProperty="Opacity"
                                                         To="1"
                                                         Duration="0" />
                                        <DoubleAnimation Storyboard.TargetName="FocusVisualBlack"
                                                         Storyboard.TargetProperty="Opacity"
                                                         To="1"
                                                         Duration="0" />
                                    </Storyboard>
                                </VisualState>
                                <VisualState x:Name="Unfocused" />
                                <VisualState x:Name="PointerFocused" />
                            </VisualStateGroup>
                        </VisualStateManager.VisualStateGroups>
                        <Border Background="{TemplateBinding Background}"
                                BorderBrush="{TemplateBinding BorderBrush}"
                                BorderThickness="{TemplateBinding BorderThickness}"
                                Margin="3">
                            <Border.Resources>
                                <ControlTemplate x:Key="HorizontalNextTemplate"
                                                 TargetType="Button">
                                    <Border x:Name="Root"
                                            Background="{StaticResource FlipViewButtonBackgroundThemeBrush}"
                                            BorderThickness="{StaticResource FlipViewButtonBorderThemeThickness}"
                                            BorderBrush="{StaticResource FlipViewButtonBorderThemeBrush}">
                                        <VisualStateManager.VisualStateGroups>
                                            <VisualStateGroup x:Name="CommonStates">
                                                <VisualState x:Name="Normal" />
                                                <VisualState x:Name="PointerOver">
                                                    <Storyboard>
                                                        <ObjectAnimationUsingKeyFrames Storyboard.TargetName="Root"
                                                                                       Storyboard.TargetProperty="Background">
                                                            <DiscreteObjectKeyFrame KeyTime="0"
                                                                                    Value="{StaticResource FlipViewButtonPointerOverBackgroundThemeBrush}" />
                                                        </ObjectAnimationUsingKeyFrames>
                                                        <ObjectAnimationUsingKeyFrames Storyboard.TargetName="Root"
                                                                                       Storyboard.TargetProperty="BorderBrush">
                                                            <DiscreteObjectKeyFrame KeyTime="0"
                                                                                    Value="{StaticResource FlipViewButtonPointerOverBorderThemeBrush}" />
                                                        </ObjectAnimationUsingKeyFrames>
                                                        <ObjectAnimationUsingKeyFrames Storyboard.TargetName="Arrow"
                                                                                       Storyboard.TargetProperty="Fill">
                                                            <DiscreteObjectKeyFrame KeyTime="0"
                                                                                    Value="{StaticResource FlipViewButtonPointerOverForegroundThemeBrush}" />
                                                        </ObjectAnimationUsingKeyFrames>
                                                    </Storyboard>
                                                </VisualState>
                                                <VisualState x:Name="Pressed">
                                                    <Storyboard>
                                                        <ObjectAnimationUsingKeyFrames Storyboard.TargetName="Root"
                                                                                       Storyboard.TargetProperty="Background">
                                                            <DiscreteObjectKeyFrame KeyTime="0"
                                                                                    Value="{StaticResource FlipViewButtonPressedBackgroundThemeBrush}" />
                                                        </ObjectAnimationUsingKeyFrames>
                                                        <ObjectAnimationUsingKeyFrames Storyboard.TargetName="Root"
                                                                                       Storyboard.TargetProperty="BorderBrush">
                                                            <DiscreteObjectKeyFrame KeyTime="0"
                                                                                    Value="{StaticResource FlipViewButtonPressedBorderThemeBrush}" />
                                                        </ObjectAnimationUsingKeyFrames>
                                                        <ObjectAnimationUsingKeyFrames Storyboard.TargetName="Arrow"
                                                                                       Storyboard.TargetProperty="Fill">
                                                            <DiscreteObjectKeyFrame KeyTime="0"
                                                                                    Value="{StaticResource FlipViewButtonPressedForegroundThemeBrush}" />
                                                        </ObjectAnimationUsingKeyFrames>
                                                    </Storyboard>
                                                </VisualState>
                                            </VisualStateGroup>
                                        </VisualStateManager.VisualStateGroups>
                                        <Path x:Name="Arrow"
                                              Data="M4.12,0 L9.67,5.47 L4.12,10.94 L0,10.88 L5.56,5.47 L0,0.06 z"
                                              Fill="{StaticResource FlipViewButtonForegroundThemeBrush}"
                                              Width="9.67"
                                              Height="10.94"
                                              Stretch="Fill"
                                              HorizontalAlignment="Center"
                                              VerticalAlignment="Center"
                                              UseLayoutRounding="False" />
                                    </Border>
                                </ControlTemplate>
                                <ControlTemplate x:Key="HorizontalPreviousTemplate"
                                                 TargetType="Button">
                                    <Border x:Name="Root"
                                            Background="{StaticResource FlipViewButtonBackgroundThemeBrush}"
                                            BorderThickness="{StaticResource FlipViewButtonBorderThemeThickness}"
                                            BorderBrush="{StaticResource FlipViewButtonBorderThemeBrush}">
                                        <VisualStateManager.VisualStateGroups>
                                            <VisualStateGroup x:Name="CommonStates">
                                                <VisualState x:Name="Normal" />
                                                <VisualState x:Name="PointerOver">
                                                    <Storyboard>
                                                        <ObjectAnimationUsingKeyFrames Storyboard.TargetName="Root"
                                                                                       Storyboard.TargetProperty="Background">
                                                            <DiscreteObjectKeyFrame KeyTime="0"
                                                                                    Value="{StaticResource FlipViewButtonPointerOverBackgroundThemeBrush}" />
                                                        </ObjectAnimationUsingKeyFrames>
                                                        <ObjectAnimationUsingKeyFrames Storyboard.TargetName="Root"
                                                                                       Storyboard.TargetProperty="BorderBrush">
                                                            <DiscreteObjectKeyFrame KeyTime="0"
                                                                                    Value="{StaticResource FlipViewButtonPointerOverBorderThemeBrush}" />
                                                        </ObjectAnimationUsingKeyFrames>
                                                        <ObjectAnimationUsingKeyFrames Storyboard.TargetName="Arrow"
                                                                                       Storyboard.TargetProperty="Fill">
                                                            <DiscreteObjectKeyFrame KeyTime="0"
                                                                                    Value="{StaticResource FlipViewButtonPointerOverForegroundThemeBrush}" />
                                                        </ObjectAnimationUsingKeyFrames>
                                                    </Storyboard>
                                                </VisualState>
                                                <VisualState x:Name="Pressed">
                                                    <Storyboard>
                                                        <ObjectAnimationUsingKeyFrames Storyboard.TargetName="Root"
                                                                                       Storyboard.TargetProperty="Background">
                                                            <DiscreteObjectKeyFrame KeyTime="0"
                                                                                    Value="{StaticResource FlipViewButtonPressedBackgroundThemeBrush}" />
                                                        </ObjectAnimationUsingKeyFrames>
                                                        <ObjectAnimationUsingKeyFrames Storyboard.TargetName="Root"
                                                                                       Storyboard.TargetProperty="BorderBrush">
                                                            <DiscreteObjectKeyFrame KeyTime="0"
                                                                                    Value="{StaticResource FlipViewButtonPressedBorderThemeBrush}" />
                                                        </ObjectAnimationUsingKeyFrames>
                                                        <ObjectAnimationUsingKeyFrames Storyboard.TargetName="Arrow"
                                                                                       Storyboard.TargetProperty="Fill">
                                                            <DiscreteObjectKeyFrame KeyTime="0"
                                                                                    Value="{StaticResource FlipViewButtonPressedForegroundThemeBrush}" />
                                                        </ObjectAnimationUsingKeyFrames>
                                                    </Storyboard>
                                                </VisualState>
                                            </VisualStateGroup>
                                        </VisualStateManager.VisualStateGroups>
                                        <Path x:Name="Arrow"
                                              Data="M5.55,0 L9.67,0.06 L4.12,5.47 L9.67,10.88 L5.55,10.94 L0,5.48 z"
                                              Fill="{StaticResource FlipViewButtonForegroundThemeBrush}"
                                              Width="9.67"
                                              Height="10.94"
                                              Stretch="Fill"
                                              HorizontalAlignment="Center"
                                              VerticalAlignment="Center"
                                              UseLayoutRounding="False" />
                                    </Border>
                                </ControlTemplate>
                                <ControlTemplate x:Key="VerticalNextTemplate"
                                                 TargetType="Button">
                                    <Border x:Name="Root"
                                            Background="{StaticResource FlipViewButtonBackgroundThemeBrush}"
                                            BorderThickness="{StaticResource FlipViewButtonBorderThemeThickness}"
                                            BorderBrush="{StaticResource FlipViewButtonBorderThemeBrush}">
                                        <VisualStateManager.VisualStateGroups>
                                            <VisualStateGroup x:Name="CommonStates">
                                                <VisualState x:Name="Normal" />
                                                <VisualState x:Name="PointerOver">
                                                    <Storyboard>
                                                        <ObjectAnimationUsingKeyFrames Storyboard.TargetName="Root"
                                                                                       Storyboard.TargetProperty="Background">
                                                            <DiscreteObjectKeyFrame KeyTime="0"
                                                                                    Value="{StaticResource FlipViewButtonPointerOverBackgroundThemeBrush}" />
                                                        </ObjectAnimationUsingKeyFrames>
                                                        <ObjectAnimationUsingKeyFrames Storyboard.TargetName="Root"
                                                                                       Storyboard.TargetProperty="BorderBrush">
                                                            <DiscreteObjectKeyFrame KeyTime="0"
                                                                                    Value="{StaticResource FlipViewButtonPointerOverBorderThemeBrush}" />
                                                        </ObjectAnimationUsingKeyFrames>
                                                        <ObjectAnimationUsingKeyFrames Storyboard.TargetName="Arrow"
                                                                                       Storyboard.TargetProperty="Fill">
                                                            <DiscreteObjectKeyFrame KeyTime="0"
                                                                                    Value="{StaticResource FlipViewButtonPointerOverForegroundThemeBrush}" />
                                                        </ObjectAnimationUsingKeyFrames>
                                                    </Storyboard>
                                                </VisualState>
                                                <VisualState x:Name="Pressed">
                                                    <Storyboard>
                                                        <ObjectAnimationUsingKeyFrames Storyboard.TargetName="Root"
                                                                                       Storyboard.TargetProperty="Background">
                                                            <DiscreteObjectKeyFrame KeyTime="0"
                                                                                    Value="{StaticResource FlipViewButtonPressedBackgroundThemeBrush}" />
                                                        </ObjectAnimationUsingKeyFrames>
                                                        <ObjectAnimationUsingKeyFrames Storyboard.TargetName="Root"
                                                                                       Storyboard.TargetProperty="BorderBrush">
                                                            <DiscreteObjectKeyFrame KeyTime="0"
                                                                                    Value="{StaticResource FlipViewButtonPressedBorderThemeBrush}" />
                                                        </ObjectAnimationUsingKeyFrames>
                                                        <ObjectAnimationUsingKeyFrames Storyboard.TargetName="Arrow"
                                                                                       Storyboard.TargetProperty="Fill">
                                                            <DiscreteObjectKeyFrame KeyTime="0"
                                                                                    Value="{StaticResource FlipViewButtonPressedForegroundThemeBrush}" />
                                                        </ObjectAnimationUsingKeyFrames>
                                                    </Storyboard>
                                                </VisualState>
                                            </VisualStateGroup>
                                        </VisualStateManager.VisualStateGroups>
                                        <Path x:Name="Arrow"
                                              Data="M0.06,0 L5.47,5.56 L10.88,0 L10.94,4.12 L5.48,9.67 L0,4.12 z"
                                              Fill="{StaticResource FlipViewButtonForegroundThemeBrush}"
                                              Width="10.94"
                                              Height="9.67"
                                              Stretch="Fill"
                                              HorizontalAlignment="Center"
                                              VerticalAlignment="Center"
                                              UseLayoutRounding="False" />
                                    </Border>
                                </ControlTemplate>
                                <ControlTemplate x:Key="VerticalPreviousTemplate"
                                                 TargetType="Button">
                                    <Border x:Name="Root"
                                            Background="{StaticResource FlipViewButtonBackgroundThemeBrush}"
                                            BorderThickness="{StaticResource FlipViewButtonBorderThemeThickness}"
                                            BorderBrush="{StaticResource FlipViewButtonBorderThemeBrush}">
                                        <VisualStateManager.VisualStateGroups>
                                            <VisualStateGroup x:Name="CommonStates">
                                                <VisualState x:Name="Normal" />
                                                <VisualState x:Name="PointerOver">
                                                    <Storyboard>
                                                        <ObjectAnimationUsingKeyFrames Storyboard.TargetName="Root"
                                                                                       Storyboard.TargetProperty="Background">
                                                            <DiscreteObjectKeyFrame KeyTime="0"
                                                                                    Value="{StaticResource FlipViewButtonPointerOverBackgroundThemeBrush}" />
                                                        </ObjectAnimationUsingKeyFrames>
                                                        <ObjectAnimationUsingKeyFrames Storyboard.TargetName="Root"
                                                                                       Storyboard.TargetProperty="BorderBrush">
                                                            <DiscreteObjectKeyFrame KeyTime="0"
                                                                                    Value="{StaticResource FlipViewButtonPointerOverBorderThemeBrush}" />
                                                        </ObjectAnimationUsingKeyFrames>
                                                        <ObjectAnimationUsingKeyFrames Storyboard.TargetName="Arrow"
                                                                                       Storyboard.TargetProperty="Fill">
                                                            <DiscreteObjectKeyFrame KeyTime="0"
                                                                                    Value="{StaticResource FlipViewButtonPointerOverForegroundThemeBrush}" />
                                                        </ObjectAnimationUsingKeyFrames>
                                                    </Storyboard>
                                                </VisualState>
                                                <VisualState x:Name="Pressed">
                                                    <Storyboard>
                                                        <ObjectAnimationUsingKeyFrames Storyboard.TargetName="Root"
                                                                                       Storyboard.TargetProperty="Background">
                                                            <DiscreteObjectKeyFrame KeyTime="0"
                                                                                    Value="{StaticResource FlipViewButtonPressedBackgroundThemeBrush}" />
                                                        </ObjectAnimationUsingKeyFrames>
                                                        <ObjectAnimationUsingKeyFrames Storyboard.TargetName="Root"
                                                                                       Storyboard.TargetProperty="BorderBrush">
                                                            <DiscreteObjectKeyFrame KeyTime="0"
                                                                                    Value="{StaticResource FlipViewButtonPressedBorderThemeBrush}" />
                                                        </ObjectAnimationUsingKeyFrames>
                                                        <ObjectAnimationUsingKeyFrames Storyboard.TargetName="Arrow"
                                                                                       Storyboard.TargetProperty="Fill">
                                                            <DiscreteObjectKeyFrame KeyTime="0"
                                                                                    Value="{StaticResource FlipViewButtonPressedForegroundThemeBrush}" />
                                                        </ObjectAnimationUsingKeyFrames>
                                                    </Storyboard>
                                                </VisualState>
                                            </VisualStateGroup>
                                        </VisualStateManager.VisualStateGroups>
                                        <Path x:Name="Arrow"
                                              Data="M5.63,0 L11.11,5.55 L11.05,9.67 L5.64,4.12 L0.23,9.67 L0.17,5.55 z"
                                              Fill="{StaticResource FlipViewButtonForegroundThemeBrush}"
                                              Width="10.94"
                                              Height="9.67"
                                              Stretch="Fill"
                                              HorizontalAlignment="Center"
                                              VerticalAlignment="Center"
                                              UseLayoutRounding="False" />
                                    </Border>
                                </ControlTemplate>
                            </Border.Resources>
                            <Grid>
                                <ScrollViewer x:Name="ScrollingHost"
                                              VerticalSnapPointsType="MandatorySingle"
                                              HorizontalSnapPointsType="MandatorySingle"
                                              HorizontalScrollMode="{TemplateBinding ScrollViewer.HorizontalScrollMode}"
                                              HorizontalScrollBarVisibility="{TemplateBinding ScrollViewer.HorizontalScrollBarVisibility}"
                                              VerticalScrollMode="{TemplateBinding ScrollViewer.VerticalScrollMode}"
                                              VerticalScrollBarVisibility="{TemplateBinding ScrollViewer.VerticalScrollBarVisibility}"
                                              IsHorizontalRailEnabled="{TemplateBinding ScrollViewer.IsHorizontalRailEnabled}"
                                              IsVerticalRailEnabled="{TemplateBinding ScrollViewer.IsVerticalRailEnabled}"
                                              IsHorizontalScrollChainingEnabled="{TemplateBinding ScrollViewer.IsHorizontalScrollChainingEnabled}"
                                              IsVerticalScrollChainingEnabled="{TemplateBinding ScrollViewer.IsVerticalScrollChainingEnabled}"
                                              IsDeferredScrollingEnabled="{TemplateBinding ScrollViewer.IsDeferredScrollingEnabled}"
                                              BringIntoViewOnFocusChange="{TemplateBinding ScrollViewer.BringIntoViewOnFocusChange}"
                                              Padding="{TemplateBinding Padding}"
                                              ZoomMode="Disabled"
                                              TabNavigation="{TemplateBinding TabNavigation}"
                                              IsTabStop="False">
                                    <ItemsPresenter />
                                </ScrollViewer>

                                <animatedFlipView:ScrollViewerOffsetMediator x:Name="Mediator"
                                                                             ScrollViewer="{Binding ElementName=ScrollingHost}" />

                                <Button x:Name="PreviousButtonHorizontal"
                                        Template="{StaticResource HorizontalPreviousTemplate}"
                                        Width="70"
                                        Height="40"
                                        IsTabStop="False"
                                        HorizontalAlignment="Left"
                                        VerticalAlignment="Center" />
                                <Button x:Name="NextButtonHorizontal"
                                        Template="{StaticResource HorizontalNextTemplate}"
                                        Width="70"
                                        Height="40"
                                        IsTabStop="False"
                                        HorizontalAlignment="Right"
                                        VerticalAlignment="Center" />
                                <Button x:Name="PreviousButtonVertical"
                                        Template="{StaticResource VerticalPreviousTemplate}"
                                        Width="70"
                                        Height="40"
                                        IsTabStop="False"
                                        HorizontalAlignment="Center"
                                        VerticalAlignment="Top" />
                                <Button x:Name="NextButtonVertical"
                                        Template="{StaticResource VerticalNextTemplate}"
                                        Width="70"
                                        Height="40"
                                        IsTabStop="False"
                                        HorizontalAlignment="Center"
                                        VerticalAlignment="Bottom" />
                            </Grid>
                        </Border>
                        <Rectangle x:Name="FocusVisualWhite"
                                   IsHitTestVisible="False"
                                   Stroke="{StaticResource FocusVisualWhiteStrokeThemeBrush}"
                                   StrokeEndLineCap="Square"
                                   StrokeDashArray="1,1"
                                   Opacity="0"
                                   StrokeDashOffset="1.5" />
                        <Rectangle x:Name="FocusVisualBlack"
                                   IsHitTestVisible="False"
                                   Stroke="{StaticResource FocusVisualBlackStrokeThemeBrush}"
                                   StrokeEndLineCap="Square"
                                   StrokeDashArray="1,1"
                                   Opacity="0"
                                   StrokeDashOffset="0.5" />
                    </Grid>
                </ControlTemplate>
            </Setter.Value>
        </Setter>
    </Style>

For simplicity purpose, I’ve only managed the horizontal changes in the FlipView but it should be really simple to perform the same thing for the vertical changes!

 

Happy coding!