win8dev

all my win8dev posts

How to add and consume an AppService to your UWP app (complete walkthrough)

One of the very cool and helpful new features Microsoft added for UWP apps are AppServices. AppServices allow your application to provide functionality to other applications without even being launched. This post shows how to add and consume an AppService.

Creating the AppService

An AppService is a background task that is hosted by your application. To add an AppService to your existing application, right click on the solution name in the Solution Explorer and select ‘add new  project’. Under category Windows\Universal, select ‘Windows Runtime Component’, give it a name and click on ‘OK’:

image

This adds a new project to your solution. Rename or Replace Class1.cs to something that matches your need (in my sample, I just use ‘Handler’). The next step is to implement the IBackgroundTask interface:

image

This will add the ‘Run(IBackgroundTaskInstance taskInstance)’ method to the class. Before we continue with to integrate our AppService further into the system, we need to declare two members in the Handler class:

        private BackgroundTaskDeferral _backgroundTaskDeferral;
        private AppServiceConnection _appServiceConnection;

Now that we have those two in place, let’s have a look inside the Run method:

       public void Run(IBackgroundTaskInstance taskInstance)
        {
            //get the task instance deferral
            this._backgroundTaskDeferral = taskInstance.GetDeferral();

            //hooking up to the Canceled event to close app connection
            taskInstance.Canceled += OnTaskCanceled;

            //getting the AppServiceTriggerDetails and hooking up to the RequestReceived event
            var details = (AppServiceTriggerDetails)taskInstance.TriggerDetails;
            _appServiceConnection = details.AppServiceConnection;
            _appServiceConnection.RequestReceived += OnRequestReceived;
        }

The first step is to get a background task deferral. This allows the service to run asynchronous code against the background Task without crashing. The next step is to handle the background task’s Canceled event. Even if the Task get’s cancelled, we must complete the process and tell the OS that we have finished. If we won’t do this, the AppService will stop working on the first cancel operation. To do so, add this code to your Canceled event handling method:

            this._backgroundTaskDeferral?.Complete();

Last but not least, we need to handle the request that the AppService received. To do so, we need to get the AppServiceTriggerDetails from our BackgroundTask. This allows us to get  a reference to the AppServiceConnection, which provides the event ‘RequestReceived’ that we want to handle.

Within our RequestReceived event handling method, the effective work is done. As this is also an asynchronous action, we first need to get again a reference to the event’s Deferral:

var msgDeferral = args.GetDeferral();

The next step is to get the data from the event’s AppServiceRequestReceivedEventArgs:

            var input = args.Request.Message;

This gives us a ValueSet (which works like a Dictionary), which we need to parse to get the input data we need:

var response = (string) input["question"];

The ValueSet entries you are setting up here are the parameters your consumer has to provide. In my sample, I have only a single parameter called ‘question’, but it works also well with more parameters. After we pulled the parameters out of the ValueSet, we can do the work our AppService is supposed to do.

It is a good practice to separate the function you want to provide in the AppService in a separate project. You need to write the code only once, but can use it in your main application as well as in the AppService. In my Sample, this is done in the AppServiceResponder project. It may look like an overkill in this case, but if you have more complex logic than the sample it will absolutely make sense.

I am wrapping the work into a try/finally block as we need to complete the async operation in any case to keep our AppService running. This way, even if the work is not completed successfully, at least we come out clean of the AppService Task. Within the try part of the try/finally block, we are doing the work that the service is supposed to do. The result needs to be passed as a ValueSet again. To effectively send the result to the requesting app, we use this line of code:

await args.Request.SendResponseAsync(result);

Here is the full method for reference:

        private async void OnRequestReceived(AppServiceConnection sender, AppServiceRequestReceivedEventArgs args)
        {
            //async operation needs a deferral
            var msgDeferral = args.GetDeferral();


            //picking up the data ValueSet
            var input = args.Request.Message;
            var result = new ValueSet();

            //parsing the ValueSet
            var response = (string) input["question"];

            try
            {
                //as long as the app service connection is established we are using the same instance even if data changes.
                //to avoid crashes, clear the result before getting the new one
                result.Clear();

                if (!string.IsNullOrEmpty(response))
                {
                    var responderResponse = AppServiceResponder.Responder.Instance.GetResponse(response);

                    result.Add("Status", "OK");
                    result.Add("response", responderResponse);
                }

                await args.Request.SendResponseAsync(result);
            }
            //using finally because we need to tell the OS we have finished, no matter of the result
            finally
            {
                msgDeferral?.Complete();
            }
        }

Declaring the App Service in the host app

The final step we need to apply is to declare the AppService in our Package.appxmanifest. Declaring the AppService is pretty simple. Just select ‘App Service’ in the dropdown and hit ‘Add’. Give it a name (Microsoft recommends ‘reverse domain name style ‘,  so I used it. The last step is to declare the Entry point, which is AppServiceNamespace.ClassName (replace with yours).

The result should look like this:

image

Now build the solution. If all is set up correct, you have made an application implementing an AppService.

Creating the AppService Connector

Like I recommend to extract functionality that runs inside the AppService, I do so for the code that connects the app into a separate project. This allows you to reuse the project in multiple apps. An additional advantage is that you can create a Nuget package for this separate project to provide this functionality to other developers (I will write a separate post about this to keep this one focused on the AppService).

After adding a new project to the Solution, rename/replace also here Class1. I named my handler class just Connector. To make it a no brainer to use the connector, I implemented the class as singleton:

        private static Connector _instance;
        public static Connector Instance => _instance ?? (_instance = new Connector());

After that, I added an asynchronous Task that returns the AppService’s response. Let’s have a look inside the task. Inside the using statement for the AppServiceconnection, the first thing we need to do is to call the AppService with these three lines of code:

                //declaring the service and the package family name
                SampleAppServiceConnection.AppServiceName = "com.msiccdev.sampleappservice";

                //this one can be found in the Package.appxmanifest file
                SampleAppServiceConnection.PackageFamilyName = "acc75b1a-8b90-4f18-a2c4-08b0d700f1c6_62er76fr5b6k0";

                //trying to connect to he AppService
                AppServiceConnectionStatus status = await SampleAppServiceConnection.OpenAsync();

We’ll get a AppServiceConnectionStatus back, which helps us to deside how to go on in the task. If we do not have success in getting a connection to the AppService, I am returning an error description. For this, I created a simple helper method:

        private string GetStatusDetail(AppServiceConnectionStatus status)
        {
            var result = "";
            switch (status)
            {
                case AppServiceConnectionStatus.Success:
                    result = "connected";
                    break;
                case AppServiceConnectionStatus.AppNotInstalled:
                    result = "AppServiceSample seems to be not installed";
                    break;
                case AppServiceConnectionStatus.AppUnavailable:
                    result =
                        "App is currently not available (could be running an update or the drive it was installed to is not available)";
                    break;
                case AppServiceConnectionStatus.AppServiceUnavailable:
                    result = "App is installed, but the Service does not respond";
                    break;
                case AppServiceConnectionStatus.Unknown:
                    result = "Unknown error with the AppService";
                    break;
            }

            return result;
        }

For the case we are successful with our connection attempt , I am sending the needed ValueSet with these lines:

                    var input = new ValueSet() {{"question", question}};
                    AppServiceResponse response = await SampleAppServiceConnection.SendMessageAsync(input);

I am using a simple ValueSet with just one value here, but I have already done it with a more complex structure and this works as well. I haven’t reached any limits by now, but I think that they are the same as for all Background Tasks (don’t throw stones at me if it is different). The only thing I then need to do is to handle the response according to its status with this switch statement:

                    switch (response.Status)
                    {
                        case AppServiceResponseStatus.Success:
                            result = (string) response.Message["response"];
                            break;
                        case AppServiceResponseStatus.Failure:
                            result = "app service called failed, most likely due to wrong parameters sent to it";
                            break;
                        case AppServiceResponseStatus.ResourceLimitsExceeded:
                            result = "app service exceeded the resources allocated to it and had to be terminated";
                            break;
                        case AppServiceResponseStatus.Unknown:
                            result = "unknown error while sending the request";
                            break;
                    }

As we already know by know, we receive a ValueSet as response message. In my sample, I am returning only the response string. That’s it, we are already able to run use the AppService via the Connector. For demo purposes, I added also a simple AppService consumer app. Once the user puts in a question and hits the answer button, the result from the AppService gets displayed. All we need is just one line of code:

            AnswerTextBlock.Text = await SampleAppServiceConnector.Connector.Instance.GetResponse(QuestionTextBox.Text);

Pretty easy to use, right? Here is a screen shot from the consumer app:

image

That’s all we need for our AppService. Bonus of the project structure I used: You can provide a Nuget Package for other devs to consume your AppService. How? I will write about this in my next blog post.

Even if this is not a MVVM structured app, it absolutely works in there, too. If you want to have a look on a live in the Store app that uses MVVM and an AppService, click here. For using the AppService within your app, just download this Nuget Package into your app. Otherwise, I created a complete working sample and pushed it on my Github account right here. Feel free to play around with it to explore AppServices a bit more. As always, I hope this post is helpful for some of you.

Happy coding, everyone!

Posted by msicc in Dev Stories, UWP, win8dev, wpdev, 3 comments

How to implement a simple notification system in MVVM Windows 8.1 Universal apps

screenshot_07042015_152814

If your app performs actions, you most probably want to add also some confirmation if an action has finished. There are some ways to do this, like using local toast notifications or MessageDialogs. While I was working on Voices Admin v2, which is a universal app, I came along with a helper to simplify using local toast notifications. However, there came the point, where I got annoyed by the sound of these, and I looked into possible ways to replace them. My solution is a simple notification system, that uses the MVVM Light Messenger.

The first thing I did was adding a new property that broadcasts its PropertyChangedMessage to my ExtendedViewModelBase (which inherits from the MVVM Light ViewModelBase). This simplifies setting the notification text across multiple ViewModels as I don’t need to create a property in every ViewModel of my app:

public class ExtendedViewModelBase : ViewModelBase
    {
        public ExtendedViewModelBase()
        {
            
        }


        /// <summary>
        /// The <see cref="NotificationText" /> property's name.
        /// </summary>
        public const string NotificationTextPropertyName = "NotificationText";

        private string _notificationText = string.Empty;

        /// <summary>
        /// Sets and gets the NotificationText property.
        /// Changes to that property's value raise the PropertyChanged event. 
        /// This property's value is broadcasted by the MessengerInstance when it changes.
        /// </summary>
        public string NotificationText
        {
            get
            {
                return  _notificationText = string.Empty;
            }
            set
            {
                Set(() => NotificationText, ref _notificationText, value, true);
            }
        }
   }

The second step is to create the possibility to bind this into my view. I am using a custom PageBase class to simplify this. For those binding purposes it is common to add a DependencyProperty, and this is exactly what I did:

/// <summary>
        /// global property to bind the notification text against
        /// </summary>
        public static readonly DependencyProperty AppNotificationTextProperty = DependencyProperty.Register(
            "AppNotificationText", typeof (string), typeof (PageBase), new PropertyMetadata(string.Empty, (s, e) =>
            {
                var current = s as PageBase;

                if (current == null)
                {
                    return;
                }

                current.CheckifNotificationMessageIsNeeded(s);
            }));

        /// <summary>
        /// gets or sets the AppNotificationText
        /// </summary>
        public string AppNotificationText
        {
            get { return (string)GetValue(AppNotificationTextProperty); }
            set { SetValue(AppNotificationTextProperty, value); }}

You may have noticed that I hooked up into the PropertyChangedCallback of the DependecyProperty, which passes the execution to an separate method. Before we’ll have a look on that method, we need to add two private members to my PageBase: one for a StackPanel (mainly to set the Background color) and another one for Textblock. This is needed because this is the visible part of the notification. In the constructor of my PageBase class, I am filling them with live and connect them together:

            //instantiate and create StackPanel and TextBlock
            //you can put anything you want in the panel
            _panel = new StackPanel()
            {
                Background = new SolidColorBrush(Colors.Blue),
                Visibility = Visibility.Collapsed,
            };

            _textBlock = new TextBlock()
            {
                FontSize = 20,
                Margin = new Thickness(39, 10, 10, 10),
                TextAlignment = TextAlignment.Center
            };
            _panel.Children.Add(_textBlock);

The next thing we need to do is the FindChildren<T> helper method, which I took from the MSDN docs:

        /// <summary>
        /// Gets a list of DependencyObjects from the Visual Tree
        /// </summary>
        /// <typeparam name="T">the type of the desired object</typeparam>
        /// <param name="results">List of children</param>
        /// <param name="startNode">the DependencyObject to start the search with</param>
        public static void FindChildren<T>(List<T> results, DependencyObject startNode) where T : DependencyObject
        {
            int count = VisualTreeHelper.GetChildrenCount(startNode);
            for (int i = 0; i < count; i++)
            {
                var current = VisualTreeHelper.GetChild(startNode, i);
                if ((current.GetType()) == typeof(T) || (current.GetType().GetTypeInfo().IsSubclassOf(typeof(T))))
                {
                    T asType = (T)current;
                    results.Add(asType);
                }
                FindChildren<T>(results, current);
            }
         }

This helper enables us to find the top level grid, where we will add the StackPanel and control its visibilty and the TextBlock’s text. Which we are doing with the CheckifNotificationMessageIsNeeded() method:

        /// <summary>
        /// handles the visibility of the notification
        /// </summary>
        /// <param name="currentDependencyObject">the primary depenedency object to start with</param>
        private void CheckifNotificationMessageIsNeeded(DependencyObject currentDependencyObject)
        {
            if (currentDependencyObject == null) return;

            var children = new List<DependencyObject>();
            FindChildren(children, currentDependencyObject);
            if (children.Count == 0) return;

            var rootGrid = (Grid)children.FirstOrDefault(i => i.GetType() == typeof(Grid));

            if (rootGrid != null)

                if (!string.IsNullOrEmpty(AppNotificationText))
                {
                    if (!rootGrid.Children.Contains(_panel))
                    {
                        rootGrid.RowDefinitions.Add(new RowDefinition() {Height = new GridLength(_panel.ActualHeight, GridUnitType.Auto)});
                        _panel.SetValue(Grid.RowProperty, rootGrid.RowDefinitions.Count);

                        rootGrid.Children.Add(_panel);
                    }

                    _textBlock.Text = AppNotificationText;
                    _panel.Visibility = Visibility.Visible;
                }
                else if (string.IsNullOrEmpty(AppNotificationText))
                {
                    _textBlock.Text = string.Empty;
                    _panel.Visibility = Visibility.Collapsed;
                }
        }

Once we have the rootGrid on our Page, we are adding a new Row, set the StackPanel’s Grid.Row property to that and finally add the StackPanel to the Grid’s Children – but only if it does not exist already. No everytime the AppNotificationText property changes, the visibility of the StackPanel changes accordingly. Same counts for the TextBlock’s text. That’s all we need to do in the PageBase class.

The final bits of code we have to add are in the MainViewModel. I am using the MainViewModel as a kind of root ViewModel, which controls values and actions that are needed across multiple ViewModels. If you do not use it in the same way, you might need to write that code in all of your ViewModels where you want to use the notifications. The biggest advantage of my way is that the notification system (and other things) also works across pages.

The first thing we need is of course a property for the notification Text, which we will use to bind against on all pages where we want to use the notification system:

        /// <summary>
        /// The <see cref="GlobalNotificationText" /> property's name.
        /// </summary>
        public const string GlobalNotificationTextPropertyName = "GlobalNotificationText";

        private string _globalNotificationText = string.Empty;

        /// <summary>
        /// Sets and gets the GlobalNotificationText property.
        /// Changes to that property's value raise the PropertyChanged event. 
        /// </summary>
        public string GlobalNotificationText
        {
            get
            {
                return _globalNotificationText;
            }
            set
            {
                Set(() => GlobalNotificationText, ref _globalNotificationText, value);
            }
        }

Now we have this, we are hooking into the MVVM Messenger to catch the broadcasted NotificationText’s PropertyChangedMessage:

            Messenger.Default.Register<PropertyChangedMessage<string>>(this, message =>
            {
                if (message.PropertyName == ExtendedViewModelBase.NotificationTextPropertyName)
                {
                }
             });

If we would stop here, you would need to find a good point to set the NotificationText (and/or the GlobalNotificationText) property back to an empty string. This can be like the search a needle in the hay, believe me. That’s why I am giving every notification 5 seconds to be displayed, and the I am resetting the GlobalNotificationText  property in my MainViewModel automatically. To achieve this goal, I am using a simple DispatcherTimer with an Interval of 1 second:

            _notificationTimer = new DispatcherTimer() { Interval = new TimeSpan(0, 0, 1) };

DispatcherTimer has a Tick event, which fires every time a Tick happened. In our case, it fires every second. Hooking up into this event is essential, so add this line of code and let Visual Studio create the handler for you:

//in constructor:       
_notificationTimer.Tick += _notificationTimer_Tick;

//generated handler:
        private void _notificationTimer_Tick(object sender, object e)
        {
        }

Inside the Tick event handler, I am counting the ticks (using a private member in my MainViewModel). Once the timer passed 5 seconds, I am stopping the DispatcherTimer, reset the counter and finally set the GlobalNotificationText  property back to empty, which causes the notification to disappear:

            _notificationTimerElapsedSeconds++;

            if (_notificationTimerElapsedSeconds > 5)
            {
                _notificationTimer.Stop();
                _notificationTimerElapsedSeconds = 0;
                GlobalNotificationText = string.Empty;
            }

Of course we also need to start the DispatcherTimer. The perfect time for this is within the handler of the received PropertyChangedMessage we added earlier:

            //register for the global NotificationText PropertyChangedMessage from all VMs that derive from ExtendenViewModelBase
            Messenger.Default.Register<PropertyChangedMessage<string>>(this, message =>
            {
                if (message.PropertyName == ExtendedViewModelBase.NotificationTextPropertyName)
                {
                    if (!_notificationTimer.IsEnabled)
                    {
                        _notificationTimer.Start();
                    }
                    else
                    {
                        _notificationTimerElapsedSeconds = 0;
                    }

                    GlobalNotificationText = message.NewValue;
                }
            });

I am just checking if the DispatcherTimer is not yet enabled (= running) and start the timer in this case. If it is already running, I am just resetting my counter property to make sure that the notification is visible for 5 seconds again.

That’s it. Your MVVM (Light) app has now a simple and not so annoying notification system. It also provides the same experience across both platforms. There are sure ways to improve this here and there, that’s why I put up a sample to play around and contribute to on my Github account.

As always, I hope this post is helpful for some of you.

Happy coding!

Posted by msicc in Dev Stories, win8dev, wpdev, 0 comments

How to add Microsoft Application Insights v1 to your Windows 8.1 Universal app

Late in 2014, Microsoft finally started Application Insights (AI), their own telemetry service for all kind of apps. For Windows (Phone) 8.1 apps, the service was a long running beta. This month, Microsoft finally released version 1.0 of Application Insights for Windows apps.

Screenshot (15)

However, if you are upgrading from a previous version, you will see that AI will no longer send any data to Azure. This has a very simple reason. Microsoft moved the configuration from the former ApplicationInsights.config file to a class called WindowsAppInitializer. I only found this out because I commented at the corresponding documentation site, which causes Microsoft to send me an email with a link to the solution in the forums. You will not find these info in the documentation as of writing this blog post. Microsoft also updated the docs tonight.

I strongly recommend you to remove all old references in favor of just updating to avoid any glitches with the new API.

I played around with the new WindowsAppInitializer class. If you want to collect all data with the automatic WindowsCollectors, all you have to add to your code is one line in your App.xaml.cs constructor (Microsoft recommends to add it before all other code):

WindowsAppInitializer.InitializeAsync("your instrumentation key”);

That’s it. Really. Here’s a screen shot of the test app in Visual Studio I created to play around with the new WindowsAppInitializer class:

Screenshot (24)

As you can see, telemetry data gets written to the debug output, and with that, it will be submitted to your Azure account. If you do not want to use all Collectors, just add those you want to use after your InstrumentationKey, separated with ‘|’ in the IninitalizeAsync Method.

Adding custom telemetry data collection is still possible. Quick sample:

var tc = new TelemetryClient();
tc.TrackEvent("MainPage loaded... [WP TestEvent]");

This will send this string as a custom event to your Azure account. For more info about custom telemetry data, check this page.

As always, I hope this blog post is helpful for some of you.

Happy coding!

Posted by msicc in Dev Stories, win8dev, wpdev, 1 comment

[Updated] String Encryption in Windows 8.1 Universal apps

image credit: Maksim Kabakou, Fotolia.com

image credit: Maksim Kabakou, Fotolia.com

[Updated: This post caused a lot of controversy and bad voices, but luckily also some constructive feedback. This is not the initial, but the updated version of this post.]

One of the goals of a Universal Windows app project is to simplify the life of our users. Microsoft provides access to RoamingSettings as well as the RoamingFolder to achieve this goal.

The usage of this storage is fairly simple (it is the same as using the local counterparts). However, one big point is how to save those settings and files securely. Nowadays, a lot of users are even more concerned about security than before, and it makes all sense to encrypt synchronized data.

This is how I came a long with a helper class string encryption. I have searched a lot throughout the Web, but apparently this is not a topic to be discussed openly but behind closed doors. I partly understand that, but I want to say thanks to Ginny Caughey at this point for her feedback on security, and also thank Joost van Schaik for his feedback that “forced” me to change my helper class to extension methods, which makes the usage more readable. If you want to learn more about Extension Methods, this link helped me to understand them and made me changing my code in about 5 minutes.

Let’s talk about security. There are two patterns for encrypting sensitive data: using symmetric algorithm and using asymmetric algorithm. The symmetric key encryption is secure, as long as you have a truly unique identifier that you can use as encryption key. Being very fast, using the symmetric algorithm is only as secure as the key that is used for encryption (obviously, I did it wrong in the first place, that’s why the code is updated). More security is achieved with the asymmetric algorithm, where a public and a private key are used for encryption. The downside of this higher level of security is that it takes longer to perform those actions. There are also more differences between those methods, but that would fill a whole book.

I have learned that on Android and iOS, often the AdvertisingId is used for such operations. Also Windows 8.1 (both phone and PC/tablet) have such an Id, provided by the AdvertisingManager class. Be aware that the id is per-user and per-device and users can switch this off or even reset their advertising id, so this is not a good idea to use. In Windows 8.1 Runtime projects (both phone and tablet/PC, we luckily have the PasswordVault class. This brings us some key advantages: the PasswordVault is encrypted and it does roam to trusted devices. This is what I am using for saving the keys, being it the symmetric one or the asymmetric ones.

Before we will have a look at my Extension methods, I have to put in a disclaimer. I am not saying that my way is the nonplus ultra way to encrypt strings. I do also not say that my way provides 100% security (which in fact does not even exist). My way provides security at a good level, but that level surely can be improved. I will take no responsibility for the security of apps that are using this.  

Let’s have a look at my Extension methods that will help you securing your data.

Symmetric Key Encryption

My symmetric encryption methods were using a pre shared key. I received a lot of feedback that this does not make any sense as it throws away the security factor, especially as the Guid can be recalculated. So I changed the method to use random data, that is generated from the CryptographiBuffer.GenerateRandom() method. Then I am putting this into an Base64 encoded string to pass it over to the PasswordVault:

        public static string GetKeyMaterialString(string resource = null, string username = null)
        {
            string key = "";

            if (string.IsNullOrEmpty(resource) && string.IsNullOrEmpty(username))
            {
                //replace with your resource name if suitable
                resource = "symmetricKey";
                //replace with your user's name/identifier
                username = "sampleUserName";                                
            }            

            //using try catch as FindAllByResource will throw an exception anyways if the specified resource is not found
            try
            {
                //search for our saved symmetric key
                var findSymmetricKey = _passwordVault.FindAllByResource(resource);
                //calling RetrievePassword you MUST!
                findSymmetricKey[0].RetrievePassword();
                key = findSymmetricKey[0].Password;
            }
            catch (Exception)
            {
                //getting a true random key buffer with a length of 32 bytes
                IBuffer randomKeyBuffer = CryptographicBuffer.GenerateRandom(32);

                key = CryptographicBuffer.EncodeToBase64String(randomKeyBuffer); 

                _passwordVault.Add(new PasswordCredential(resource, username, key));
            }
            
            return key;
        }

The resource string as well as the username is needed to save the key into the PasswordVault. The FindAllByResource() method will throw an Exception if no credentials are found, in this case we are generating them from scratch in the catch block.

The encryption method is pretty straight forward as well. Microsoft does all the complicated calculating stuff, we just need to call the proper methods. What you get is a Base64 encoded string that easily can be saved into the ApplicationSettings or wherever you need it. Here is the complete extension method:

        public static string EncryptStringSymmetric(this string text)
        {
            string encryptedString = "";

            try
            {
                //load the alghorithm providers
                var symmetricKeyProvider = SymmetricKeyAlgorithmProvider.OpenAlgorithm(SymmetricAlgorithmNames.AesCbcPkcs7);

                //create the symmetric key that is used to encrypt the string from random keystring
                var cryptoKey = symmetricKeyProvider.CreateSymmetricKey(CryptographicBuffer.DecodeFromBase64String(GetKeyMaterialString()));

                //create the IBuffer that is for the string
                IBuffer buffer = CryptographicBuffer.CreateFromByteArray(Encoding.UTF8.GetBytes(text));

                //encrypt the byte array with the symmetric key
                encryptedString = CryptographicBuffer.EncodeToBase64String(CryptographicEngine.Encrypt(cryptoKey, buffer, null));

                //return the Base64 string representation of the encrypted string byte array
                return encryptedString;
            }
            catch (Exception)
            {
                return null;
            }

        }

 


The decryption method of course reverses all this. First, it loads the saved key from the password fault, and then decrypts and returns then the plain text string:

        public static string DecryptStringSymmetric(this string text)
        {
            string decryptedString = "";

            try
            {
                //load the alghorithm providers
                var symmetricKeyProvider = SymmetricKeyAlgorithmProvider.OpenAlgorithm(SymmetricAlgorithmNames.AesCbcPkcs7);

                //create the symmetric key that is used to encrypt the string from random keystring
                var cryptoKey = symmetricKeyProvider.CreateSymmetricKey(CryptographicBuffer.DecodeFromBase64String(GetKeyMaterialString()));

                //decode the input Base64 string
                IBuffer buffer = CryptographicBuffer.DecodeFromBase64String(text);
                //declare new byte array
                byte[] dectryptedBytes;
                //decrypt the IBuffer back to byte array
                CryptographicBuffer.CopyToByteArray(CryptographicEngine.Decrypt(cryptoKey, buffer, null), out dectryptedBytes);
                //get string back from the byte array
                decryptedString = Encoding.UTF8.GetString(dectryptedBytes, 0, dectryptedBytes.Length);

                //return plain text
                return decryptedString;
            }
            catch (Exception)
            {
                return null;
            }
        }

 

Both methods return null if anything did not work like excepted. This should help you to easily check if something went wrong in there. Here is how to use those methods:

Encrypting the string:

var encryptedString = stringToEncrypt.EncryptStringSymmetric();

Decrypting the string:

var dectryptedString = stringToDecrypt.DecryptStringSymmetric();

Asymmetric Key Encryption

Like I already wrote, for asymmetric encryption always two keys are used. The method to get the keys is there slightly different:

        public static Dictionary<string, string> GetAsymmetricKeyPair(string username = null)
        {
            Dictionary<string, string> keyDictionary;
            const string privKey = "asymmetricPrivateKey";
            const string pubKey = "asymmetricPublicKey";

            if (string.IsNullOrEmpty(username))
            {
                //replace with your user's name/identifier 
                username = "sampleUserName";
            }

            //using try catch as FindAllByResource will throw an exception anyways if the specified resource is not found
            try
            {
                //search for our save asymmetric keys
                var findAsymmetricPrivateKey = _passwordVault.FindAllByResource(privKey);
                //calling RetrievePassword you MUST!
                findAsymmetricPrivateKey[0].RetrievePassword();
                var findAsymmetricPublicKey = _passwordVault.FindAllByResource(pubKey);
                //calling RetrievePassword you MUST!
                findAsymmetricPublicKey[0].RetrievePassword();

                //loading our keys into a new Dictionary
                keyDictionary = new Dictionary<string, string>()
                {
                    {privKey, findAsymmetricPrivateKey[0].Password},
                    {pubKey, findAsymmetricPublicKey[0].Password}
                };
            }
            catch (Exception)
            {
                //declaring the Key Algortihm Provider and creating the KeyPair
                var asymmetricKeyProvider =
                    AsymmetricKeyAlgorithmProvider.OpenAlgorithm(AsymmetricAlgorithmNames.RsaPkcs1);
                CryptographicKey cryptographicKeyPair = asymmetricKeyProvider.CreateKeyPair(512);

                //converting the KeyPair into IBuffers
                IBuffer privateKeyBuffer =
                    cryptographicKeyPair.Export(CryptographicPrivateKeyBlobType.Pkcs1RsaPrivateKey);
                IBuffer publicKeyBuffer =
                    cryptographicKeyPair.ExportPublicKey(CryptographicPublicKeyBlobType.Pkcs1RsaPublicKey);

                //encoding the key IBuffers into Base64 Strings and adding them to a new Dictionary
                keyDictionary = new Dictionary<string, string>
                {
                    {privKey, CryptographicBuffer.EncodeToBase64String(privateKeyBuffer)},
                    {pubKey, CryptographicBuffer.EncodeToBase64String(publicKeyBuffer)}
                };

                //saving the newly generated keys in PasswordVault
                //it is recommended to save the both keys separated from each other, though
                _passwordVault.Add(new PasswordCredential(privKey, username, keyDictionary[privKey]));
                //_passwordVault.Add(new PasswordCredential(pubKey, username, keyDictionary[pubKey]));
            }

            //return new Dictionary
            return keyDictionary;
        }

As you can see, I am creating a Dictionary that holds the two keys so we can work with. I also use another key generating method, specially made for asymmetric encryption. I store those two keys separated from each other into the PasswordVault in the end.

The encryption follows basically the same structure as the symmetric key encryption method. Due to the fact I already have two different keys, I think this is ok for the scenario of passing values between the Windows Phone and Windows  project. Eventually I will change that in future when I see the need for it. Notice that for encryption, always the public key is used. The public key should also be saved separated from the private key. So here is the complete method:

        public static string EncryptStringAsymmetric(this string text, string publicKey = null)
        {
            //making sure we are providing a public key
            if (string.IsNullOrEmpty(publicKey))
            {
                var keyPairs = GetAsymmetricKeyPair();
                publicKey = keyPairs["asymmetricPublicKey"];
            }

            try
            {
                //converting the public key into an IBuffer
                IBuffer keyBuffer = CryptographicBuffer.DecodeFromBase64String(publicKey);
                
                //load the public key and the algorithm provider
                var asymmetricAlgorithmProvider = AsymmetricKeyAlgorithmProvider.OpenAlgorithm(AsymmetricAlgorithmNames.RsaPkcs1);
                var cryptoKey = asymmetricAlgorithmProvider.ImportPublicKey(keyBuffer, CryptographicPublicKeyBlobType.Pkcs1RsaPublicKey);

                //converting the string into an IBuffer
                IBuffer buffer = CryptographicBuffer.CreateFromByteArray(Encoding.UTF8.GetBytes(text));

                string encryptedString = "";

                //perform the encryption
                encryptedString = CryptographicBuffer.EncodeToBase64String(CryptographicEngine.Encrypt(cryptoKey, buffer, null));

                //return the Base64 string representation of the encrypted string
                return encryptedString;
            }
            catch (Exception)
            {
                return null;
            }

        }

The decryption of the encrypted string works also in a similar way to the symmetric one, except we are using the private key of our asymmetric key pair. To be able to do this, we need to use the ImportKeyPair method, whose name is a bit misleading in my opinion. In fact, we even need to specify that we want to import the private key and not the whole key pair. But even with that, decryption works like expected:

        public static string DecryptStringAsymmetric(this string text, string privateKey = null)
        {
            //making sure we are providing a public key
            if (string.IsNullOrEmpty(privateKey))
            {
                    var keyPairs = GetAsymmetricKeyPair();
                privateKey = keyPairs["asymmetricPrivateKey"];
            }

            try
            {
                //converting the private key into an IBuffer
                IBuffer keyBuffer = CryptographicBuffer.DecodeFromBase64String(privateKey);

                //load the private key and the algorithm provider
                var asymmetricAlgorithmProvider = AsymmetricKeyAlgorithmProvider.OpenAlgorithm(AsymmetricAlgorithmNames.RsaPkcs1);
                var cryptoKey = asymmetricAlgorithmProvider.ImportKeyPair(keyBuffer, CryptographicPrivateKeyBlobType.Pkcs1RsaPrivateKey);

                //converting the encrypted text into an IBuffer
                IBuffer buffer = CryptographicBuffer.DecodeFromBase64String(text);

                //cdecrypting the IBuffer and convert its content into a Byte array 
                byte[] decryptedBytes;
                CryptographicBuffer.CopyToByteArray(CryptographicEngine.Decrypt(cryptoKey, buffer, null), out decryptedBytes);

                string decryptedString = "";

                //getting back the plain text 
                decryptedString = Encoding.UTF8.GetString(decryptedBytes, 0, decryptedBytes.Length);

                return decryptedString;
            }
            catch (Exception)
            {
                return null;
            }
        }

Like the symmetric methods, also the asymmetric methods return null if something went wrong. Here is how to use them:

Encrypting the string:

var encryptedString = stringToEncyrpt.EncryptStringAsymmetric();

Decrypting the string:

var decryptedString = stringToDecrypt.DecryptStringAsymmetric();

As you can see, securing strings does not have to be more complicated than this. Using the PasswordVault, we have a truly secure place to store the keys (that need to be saved privately and secure), the rest is done by the methods provided by the operating system. I am by far not a security researcher or expert, but this class should provide a good level of security for string encryption in Windows 8.1 universal apps.

If you know more about security or have ideas to improve this helper class, I put up a sample project on Github where you also can play around with the class and the simple app I created for it. Feel free to contribute to this class or discuss in the comments below.

Happy coding, everyone!

Posted by msicc in Dev Stories, win8dev, wpdev, 3 comments

How to implement a bindable progress indicator (loading dots) for MVVM Windows (8.1) Universal apps

Screenshot (23)

Now that I am on a good way to understand and use the MVVM pattern, I am also finding that there are some times rather simple solutions for every day problems. One of these problems is that we don’t have a global progress indicator for Windows Universal apps. That is a little bit annoying, and so I wrote my own solution. I don’t know if this is good or bad practice, but my solution is making it globally available in a Windows Universal app. The best thing is, you just need to bind to a Boolean property to use it. No Behaviors, just the one base implementation and Binding (Yes, I am a bit excited about it). For your convenience, I attached a demo project at the end of this post.

To get the main work for this done, we are implementing our own class, inherited from the Page class. The latter one is available for Windows as well as Windows Phone, so we can define it in the shared project of our Universal app. To do so, add a new class in the shared project. I named it PageBase (as it is quite common for this scenario, as I found out).

First, we need to inherit our class from the Page class:

public abstract class PageBase : Page

Now that we have done this, we need a global available property that we can bind to. We are using a DependencyProperty to achieve this goal. To make the property reflect our changes also to the UI, we also need to hook into a PropertyChanged callback on it:

        //this DepenedencyProperty is our Binding target to get all the action done!
        public static readonly DependencyProperty IsProgressIndicatorNeededProperty = DependencyProperty.Register(
            "IsProgressIndicatorNeeded", typeof (bool), typeof (PageBase), new PropertyMetadata((bool)false, OnIsProgressIndicatorNeededChanged));

        public static void OnIsProgressIndicatorNeededChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {

        }

        //get and send the value of our Binding target
        public bool IsProgressIndicatorNeeded
        {
            get { return (bool) GetValue(IsProgressIndicatorNeededProperty); }
            set { SetValue(IsProgressIndicatorNeededProperty, value); }
        }

The next step we need to do is to find the UIElement we want the progress indicator to be in. To do so, we are going through the VisualTree and pick our desired element. This helper method (taken from the MSDN documentation) will enable us to find this element:

        //helper method to find children in the visual tree (taken from MSDN documentation)
        private static void FindChildren<T>(List<T> results, DependencyObject startNode)
          where T : DependencyObject
        {
            int count = VisualTreeHelper.GetChildrenCount(startNode);
            for (int i = 0; i < count; i++)
            {
                var current = VisualTreeHelper.GetChild(startNode, i);
                if ((current.GetType()) == typeof(T) || (current.GetType().GetTypeInfo().IsSubclassOf(typeof(T))))
                {
                    T asType = (T)current;
                    results.Add(asType);
                }
                FindChildren<T>(results, current);
            }
        }

The method goes through the VisualTree, starting at the point we are throwing in as DependecyObject and gives us a List<T> with all specified Elements. From this List we are going to pick our UIElement that will hold the progress indicator for us. Let’s create a new method that will do all the work for us:

        private void CheckIfProgressIndicatorIsNeeded(DependencyObject currentObject)
        {
        }

Notice the DependencyObject parameter? This makes it easier for us to use the method in different places (which we will, more on that later). Let’s get our list of DependencyObjects from our parameter and pick the first Grid as our desired UIElement to hold the progress indicator:

            if (currentObject == null) return;

            //getting a list of all DependencyObjects in the visual tree
            var children = new List<DependencyObject>();
            FindChildren(children, currentObject);
            if (children.Count == 0) return;

            //getting a reference to the first Grid in the visual tree
            //this can be any other UIElement you define
            var rootGrid = (Grid)children.FirstOrDefault(i => i.GetType() == typeof(Grid));

Now that we have this, we are already at the point where we need to create our progress indicator object.  I declared a class member of type ProgressBar (which needs to be instantiated in the constructor then). This is how I set it up:

            //setting up the ProgressIndicator
            //you can also create a more complex object for this, like a StackPanel with a TextBlock and the ProgressIndicator in it
            _progressIndicator.IsIndeterminate = IsProgressIndicatorNeeded;
            _progressIndicator.Height = 20;
            _progressIndicator.VerticalAlignment = VerticalAlignment.Top;

The final step in the PageBase class is to check if there is already a chikd of type ProgressBar, if not adding it to the Grid and setting it’s Visibility property to Visible if our above attached DependencyProperty has the value ‘true’:

            //showing the ProgressIndicator
            if (IsProgressIndicatorNeeded)
            {
                //only add the ProgressIndicator if there isn't already one in the rootGrid
                if (!rootGrid.Children.Contains(_progressIndicator))
                {
                    rootGrid.Children.Add(_progressIndicator);
                }
                _progressIndicator.Visibility = Visibility.Visible;
            }

If the value is ‘false’, we are setting the Visibility back to collapsed:

            //hiding the ProgressIndicator
            else
            {
                if (rootGrid.Children.Contains(_progressIndicator))
                {
                    _progressIndicator.Visibility = Visibility.Collapsed;
                }
            }

Now that we have this method in place, let’s go back to our callback method we have been hooking into earlier. To reflect the changes that we are throwing into our DependencyProperty,  we are calling our method within the PropertyChanged callback. To do so, we are getting a reference to the PageBase class, which is needed because we are in a static method. Once we have this reference, we are calling our method to show/hide the progress indicator:

        public static void OnIsProgressIndicatorNeededChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            //resolving d as PageBase to enable us calling our helper method
            var currentObject = d as PageBase;

            //avoid NullReferenceException
            if (currentObject == null)
            {
                return;
            }
            //call our helper method
            currentObject.CheckIfProgressIndicatorIsNeeded(d);
        }

That’s all, we are already able to use the global progress indicator. To use this class, you need to do a few things. First, go to the code-behind part of your page. Make the class inherit from the PageBase class:

    public sealed partial class MainPage : PageBase

Now, let’s go to the XAML part and add a reference to your class:

    xmlns:common="using:MvvmUniversalProgressIndicator.Common"

Once you have done this, replace the ‘Page’ element with the PageBase class:

<common:PageBase>
//
</common:PageBase>

After you have build the project, you should be able to set the Binding to the IsProgressIndicatorNeeded property:

    IsProgressIndicatorNeeded="{Binding IsProgressIndicatorVisible}">

If you now add two buttons to the mix, binding their Commands to change the value of the Boolean property, you will see that you can switch the loading dots on and off like you wish. That makes it pretty easy to use it in a MVVM driven application.

But what if we need to show the progress indicator as soon as we are coming to the page? No worries, we are already prepared and need only a little more code for that. In the PageBase class constructor, register for the Loaded event:

            Loaded += PageBase_Loaded;

In the Loaded event, we are calling again our main method to show the progress indicator, but this time we use the current window content as reference to start with:

        void PageBase_Loaded(object sender, RoutedEventArgs e)
        {
            //using the DispatcherHelper of MvvmLight to get it running on the UI
            DispatcherHelper.CheckBeginInvokeOnUI(() =>
            {
                //Window.Current.Content is our visual root and contains all UIElements of a page
                var visualRoot = Window.Current.Content as DependencyObject;
                CheckIfProgressIndicatorIsNeeded(visualRoot);
            });

        }

As we need to reflect changes on the UI thread, I am using the DispatcherHelper of the MvvmLight Toolkit. You can use your own preferred method as well for that. That’s all, If you now test it with setting the IsProgressIndicatorNeeded property in your page directly to ‘True’ in XAML, you will see the loading dots right from the start.

Screenshot (21)

Like always, I hope this is helpful for some of you.

Happy coding!

Download Sample project

Posted by msicc in win8dev, wpdev, 1 comment

Helper class to easily display local toast notifications (Windows Universal app)

Often , we need to display a confirmation that some action in our app has been finished (like some data has been updated etc.). There are several ways of doing this, like displaying a MessageBox or MessageDialog. This however breaks the user interaction, and a lot of users will start complaining on that if your app keeps doing so. There needs to be a better way.

With the Coding4fun Toolkit floating around, you can mimic a toast notification – sadly only on Windows Phone (at least for the moment, but Dave told me he will work on implementing it for Windows, too). Also, Toastinet library is floating around, which is also able to mimic the toast notification behavior (although for Windows Universal app, the implementation is not that intuitive as for Windows  Phone). Both are fantastic libraries that I used in the past, but I wanted a solution that is implemented easily and works with my Universal app. So I did some searching in the Web and the MSDN docs, and found out that is pretty easy to use the system toast notifications on both platforms locally.

There are 8 possible ways to format toast notifications (as you can see here in the toast template catalog). This gives us pretty much options on how a notification can be styled. However, most options just work on Windows 8.1, while Windows Phone 8.1 apps will only show the notification in the way “app logo”  “bold text”  “normal text”. However, the notification system takes care of that, so you can specify some other type on Windows 8.1, while knowing that it gets converted on Windows Phone automatically. This allows us to write a helper class that implements all possible options without any headache.

the code parts for the notification

Let’s have a look at the code parts for the notification. First, you need to add two Namespaces to the class:

using Windows.Data.Xml.Dom;
using Windows.UI.Notifications;

After that, we can start writing our code. Toast notifications are formatted using Xml. Because of this, we need to get a reference to the underlying Xml template for the system toast notification:

ToastTemplateType xmlForToast= ToastTemplateType.ToastImageAndText01; 
XmlDocument toastXml = ToastNotificationManager.GetTemplateContent(xmlForToast);

System toast notifications can hold Text (and an Image on Windows 8.1). So we need to declare the elements of the toast notification. We are using the Xml methods of the DOM namespace to get the text elements of the chosen template first:

XmlNodeList toastTextElements = xmlForToast.GetElementsByTagName("text");
toastTextElements[0].AppendChild(xmlForToast.CreateTextNode("text1"));
//additional texts, depending on the template:
//toastTextElements[1].AppendChild(xmlForToast.CreateTextNode("text2"));
//toastTextElements[2].AppendChild(xmlForToast.CreateTextNode("text3"));

This is how the image element is implemented:

XmlNodeList toastImageElement = xmlForToast.GetElementsByTagName("image");
//setting the image source uri:
if (toastImageElement != null) ((XmlElement) toastImageElement[0]).SetAttribute("src", imageSourceUri);
//setting optional alternative text for the image
if (toastImageElement != null)  ((XmlElement) toastImageElement[0]).SetAttribute("alt", imageSourceAlternativeText);

You can attach local or remote images to the toast notification, but remember this works only on Windows, not on Windows Phone.

The next part we are able to set is the duration. The duration options are long (25 seconds) and short (7 seconds). The default is short, which should be ok for most scenarios. Microsoft recommends to use long only when a personal interaction of the user is needed (like in a chat). This is how we do it:

IXmlNode toastRoot = xmlForToast.SelectSingleNode("/toast");
((XmlElement) toastRoot).SetAttribute("duration", "short");

What we are doing here is to get the root element of the template’s Xml and add a new element for the duration. Now that we finally have set all options, we are able to create our toast notification and display it to the user:

ToastNotification notification = new ToastNotification(xmlForToast);
ToastNotificationManager.CreateToastNotifier().Show(notification);

the helper class

That’s all we need to do for our local notification. You might see that always rewriting the same code just makes a lot of work. Because the code for the toast notification can be called nearly everywhere in an app (it does not matter if you are calling it from a ViewModel or code behind), I wrote this helper class that makes it even more easy to use the system toast notification locally:

    public class LocalToastHelper
    {
        public void ShowLocalToast(ToastTemplateType templateType, string toastText01, string toastText02 = null, string toastText03 = null, string imageSourceUri = null, string imageSourceAlternativeText = null, ToastDuration duration = ToastDuration.Short)
        {
            XmlDocument xmlForToast = ToastNotificationManager.GetTemplateContent(templateType);
            XmlNodeList toastTextElements = xmlForToast.GetElementsByTagName("text");

            switch (templateType)
            {
                case ToastTemplateType.ToastText01:
                case ToastTemplateType.ToastImageAndText01:
                    toastTextElements[0].AppendChild(xmlForToast.CreateTextNode(toastText01));
                    break;
                case ToastTemplateType.ToastText02:
                case ToastTemplateType.ToastImageAndText02:
                    toastTextElements[0].AppendChild(xmlForToast.CreateTextNode(toastText01));
                    if (toastText02 != null)
                    {
                        toastTextElements[1].AppendChild(xmlForToast.CreateTextNode(toastText02));
                    }
                    else
                    {
                        throw new ArgumentNullException("toastText02 must not be null when using this template type");
                        
                    }
                    ;
                    break;
                case ToastTemplateType.ToastText03:
                case ToastTemplateType.ToastImageAndText03:
                    toastTextElements[0].AppendChild(xmlForToast.CreateTextNode(toastText01));
                    if (toastText02 != null)
                    {
                        toastTextElements[1].AppendChild(xmlForToast.CreateTextNode(toastText02));
                    }
                    else
                    {
                        throw new ArgumentNullException("toastText02 must not be null when using this template type");
                    }
                    ;
                    break;
                case ToastTemplateType.ToastText04:
                case ToastTemplateType.ToastImageAndText04:
                    toastTextElements[0].AppendChild(xmlForToast.CreateTextNode(toastText01));
                    if (toastText02 != null)
                    {
                        toastTextElements[1].AppendChild(xmlForToast.CreateTextNode(toastText02));
                    }
                    else
                    {
                        throw new ArgumentNullException("toastText02 must not be null when using this template type");
                    }
                    ;
                    if (toastText03 != null)
                    {
                        toastTextElements[2].AppendChild(xmlForToast.CreateTextNode(toastText03));
                    }
                    else
                    {
                        throw new ArgumentNullException("toastText03 must not be null when using this template type");
                    }
                    ;
                    break;
            }

            switch (templateType)
            {
                case ToastTemplateType.ToastImageAndText01:
                case ToastTemplateType.ToastImageAndText02:
                case ToastTemplateType.ToastImageAndText03:
                case ToastTemplateType.ToastImageAndText04:
                    if (!string.IsNullOrEmpty(imageSourceUri))
                    {
                        XmlNodeList toastImageElement = xmlForToast.GetElementsByTagName("image");
                        if (toastImageElement != null)
                            ((XmlElement) toastImageElement[0]).SetAttribute("src", imageSourceUri);
                    }
                    else
                    {
                        throw new ArgumentNullException(
                            "imageSourceUri must not be null when using this template type");
                    }
                    if (!string.IsNullOrEmpty(imageSourceUri) && !string.IsNullOrEmpty(imageSourceAlternativeText))
                    {
                        XmlNodeList toastImageElement = xmlForToast.GetElementsByTagName("image");
                        if (toastImageElement != null)
                            ((XmlElement) toastImageElement[0]).SetAttribute("alt", imageSourceAlternativeText);
                    }
                    break;
                default:
                    break;
            }

            IXmlNode toastRoot = xmlForToast.SelectSingleNode("/toast");
            ((XmlElement) toastRoot).SetAttribute("duration", duration.ToString().ToLowerInvariant());

            ToastNotification notification = new ToastNotification(xmlForToast);
            ToastNotificationManager.CreateToastNotifier().Show(notification);
        }

        public enum ToastDuration
        {
            Short,
            Long
        }
    }

As you can see, you just need to provide the wanted parameters to the ShowLocalToast method, which will do the rest of the work for you.

One word to the second switch statement I am using. The image element needs to be set only when we are using the ToastImageAndTextXX templates. There are three ways to implement the integration: using an if with 4  “or” options, the switch statement I am using or a string comparison with String.Contains. The switch statement is the cleanest option for me, so I decided to go this way. Feel free to use any of the other ways in your implementation.

In my implementation, I added also some possible ArgumentNullExceptions to make it easy to find any usage errors.

For your convenience, I attached the source file. Just swap out the namespace with yours. Download

The usage of the class is pretty simple:

var _toastHelper = new LocalToastHelper();
_toastHelper.ShowLocalToast(ToastTemplateType.ToastText02, "This is text 1", "This is text 2");

audio options

The system toasts have another option that can be set: the toast audio. This way, you can customize the appearance of the toast a bit more. I did not implement it yet, because there are some more options and things to remind, and I haven’t checked them out all together. Once I did, I will add a second post to this one with the new information.

As always, I hope this is helpful for some of you.

Happy coding!

Posted by msicc in Dev Stories, win8dev, wpdev, 3 comments

How to easily check the pressed keyboard button with a converted event using MVVM (Windows Universal)

In case you missed it, I lately am deeply diving into MVVM. Earlier today, I wanted to implement the well loved feature that a search is performed by pressing the Enter button. Of course, this would be very easy to achieve in code behind using the KeyUpEvent (or the KeyDownEvent, if you prefer).

However, in MVVM, especially in a Universal app, this is a bit trickier. We need to route the event manually to our matching command. There are surely more ways to achieve it, but I decided to use the Behaviors SDK to achieve my goal. The first step is of course downloading the matching extension (if you haven’t done so before). To do so, click on TOOLS/Extensions and Updates in Visual Studio and install the Behaviors SDK from the list:image

The next step we need to do is to add a new Converter (I added it to the common folder, you may change this to your preferred place). As we are hooking up the KeyUpEventArgs, I called it KeyUpEventArgsConverter. After you created the class, implement the IValueConverter interface. You should now have a Convert and a ConvertBack method. We are just adding two lines of code to the Convert method:

            var args = (KeyRoutedEventArgs)value;
            return args;

That’s it for the Converter. Save the class and build the project. For the next step, we need to go to our View where the Converter should do its work. Before we can use it, we need to give our Converter a key to be identified by the Binding engine. You can do this app wide in App.xaml, or in your page:

<common:KeyUpEventArgsConverter x:Key="KeyUpEventArgsConverter"/>

Also, we need to add two more references to our View (besides the Common folder that holds our converter, that is):

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

The next step is to implement the Behavior to our input control (a TextBox in my case):

<TextBox  Header="enter search terms" PlaceholderText="search terms" Text="{Binding KnowledgeBaseSearchTerms, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" >
    <i:Interaction.Behaviors>
         <core:EventTriggerBehavior EventName="KeyUp">
             <core:InvokeCommandAction
                   Command="{Binding SearchTermKeyEventArgsCommand}"
                   InputConverter="{StaticResource KeyUpEventArgsConverter}">
             </core:InvokeCommandAction>
          </core:EventTriggerBehavior>
     </i:Interaction.Behaviors>
</TextBox>

With the EventTriggerBehavior, we are able to hook into the desired event of a control. We then only need to bind to a Command in our ViewModel and tell the Behaviors SDK that it should route the “KeyUp” event using our Converter.

Let’s have a final look at the command that handles the event:

        public RelayCommand<KeyRoutedEventArgs> SearchTermKeyEventArgsCommand
        {
            get
            {
                return _searchTermKeyEventArgsCommand
                    ?? (_searchTermKeyEventArgsCommand = new RelayCommand<KeyRoutedEventArgs>(
                    p =>
                    {
                        if (p.Key == Windows.System.VirtualKey.Enter)
                        {
                            //your code here
                        }
                    }));
            }
        }

As you can see, we are using a Command that is able to take a Generic (in my case it comes from the MVVM Light Toolkit, but there are several other version floating around). Because of this, we are finally getting the KeyRoutedEventArgs into our ViewModel and are able to use its data and properties.

The VirtualKey Enumeration holds a reference to a lot of (if not all) keys and works for both hardware and virtual keyboards. This makes this code safe to use in an Universal app.

As I am quite new to MVVM, I am not entirely sure if this way is the “best” way, but it works as expected with little efforts. I hope this will be useful for some of you.

Useful links that helped me on my way to find this solution:

http://blog.galasoft.ch/posts/2014/01/using-the-eventargsconverter-in-mvvm-light-and-why-is-there-no-eventtocommand-in-the-windows-8-1-version/

https://msdn.microsoft.com/en-us/library/windows/apps/xaml/hh868246.aspx

Happy coding, everyone!

Posted by msicc in Dev Stories, win8dev, wpdev, 0 comments

Simple helper method to detect the last page of API data (C#)

When you are working with APIs from web services, you probably ran already into the same problem that I did recently: how to detect if we are on the last page of possible API results.

Some APIs (like WordPress) use tokens to be sent as parameter  with your request, and if the token is null or empty you know that you have reached the last page. However, not all APIs are working that way (for example UserVoice).

As I am rewriting Voices Admin to be a Universal app, I came up with a simple but effective helper method that allows me to easily detect if I am on the last page. Here is what I did:

	public static bool IsLastPage(int total, int countperpage, int current)
        {
            bool value = false;

            if (current < Convert.ToInt32(Math.Ceiling(Convert.ToDouble(total)/countperpage)))
            {
                value = false;
            }

            if (current == Convert.ToInt32(Math.Ceiling(Convert.ToDouble(total)/countperpage)))
                value = true;

            return value;
        }

As you can see, I need the number of total records that can be fetched (which is returned by the API) and the property for the number per page (which is one of the optional parameters of the API). On top, I need the current page number to calculate where I am (which is also an optional parameter of the API and returned by the API result).

Now I simply need to divide the total records by the result count per page to get how many pages are used. Using the Math.Ceiling() method, I always get the correct number of pages back. What does the Math.Ceiling() method do? It just jumps up to the next absolute number, also known as “rounding toward positive infinity”.

Example: if you have 51 total records and a per page count of 10, the division will return 5.1 (which means there is only one result on the 6th page). However, we need an absolute number. Rounding the result would return 5 pages, which is wrong in this case. The Math.Ceiling() method however returns the correct value of 6.

Setting the method up as a static Boolean makes it easy to change the CanExecute property of a button for example, which will be automatically disabled if we just have loaded the last page (page 6 in my case).

As always, I hope this is helpful for some of you.

Happy coding, everyone!

Posted by msicc in Dev Stories, win8dev, wpdev, 2 comments

How to capture a photo in your Windows Phone 8.1 Runtime app – Part III: capturing and saving the photo

This is the third and last post of this series. In the first two posts I showed you how to start the preview of MediaCapture and some modifications we can apply to it. In this post, we are finally capturing and saving the photo – including the modifications we made before.

The easiest way – capture as is:

The easiest way to capture the photo is to use MediaCapture’s CapturePhotoToStorageFileAsync() method. This method shows you how to do it:

            //declare image format
            ImageEncodingProperties format = ImageEncodingProperties.CreateJpeg();

            //generate file in local folder:
            StorageFile capturefile = await ApplicationData.Current.LocalFolder.CreateFileAsync("photo_" + DateTime.Now.Ticks.ToString(), CreationCollisionOption.ReplaceExisting);

            ////take & save photo
            await captureManager.CapturePhotoToStorageFileAsync(format, capturefile);

            //show captured photo
            BitmapImage img = new BitmapImage(new Uri(capturefile.Path));
            takenImage.Source = img;
            takenImage.Visibility = Visibility.Visible;

This way however does not respect any modifications we made to the preview. The only thing that gets respected is the camera device we are using.

Respecting rotation in the captured photo:

In our ongoing sample, we are using a 90 degree rotation to display the preview element in portrait mode. Naturally, we want to port over this orientation in our captured image.

There are two ways to achieve this. We could capture the photo to a WriteableBitmap and manipulate it, or we could manipulate the image stream directly with the BitmapDecoder and  BitmapEncoder classes. We will do the latter one.

First, we need to open an InMemoryRandomAccessStream for our the captured photo. We are capturing the photo to the stream with MediaCapture’s CapturePhotoToStreamAsync() method, specifing the stream name and the image format.

The next step is to decode the stream with our BitmapDecoder. If we are performing only rotation, we can directly re-encode the InMemoryRandomAccessStream we are using. Rotating the captured photo is very simple with just setting the BitmapTransform.Rotation property to be rotated by 90 degrees, pretty much as easy as rotating the preview.

The last steps are generating a file in the storage, followed by copying the transcoded image stream into the file stream. Here is the complete code that does all this:

            //declare string for filename
            string captureFileName = string.Empty;
            //declare image format
            ImageEncodingProperties format = ImageEncodingProperties.CreateJpeg();

            //rotate and save the image
            using (var imageStream = new InMemoryRandomAccessStream())
            {
                //generate stream from MediaCapture
                await captureManager.CapturePhotoToStreamAsync(format, imageStream);

                //create decoder and encoder
                BitmapDecoder dec = await BitmapDecoder.CreateAsync(imageStream);
                BitmapEncoder enc = await BitmapEncoder.CreateForTranscodingAsync(imageStream, dec);

                //roate the image
                enc.BitmapTransform.Rotation = BitmapRotation.Clockwise90Degrees;

                //write changes to the image stream
                await enc.FlushAsync();

                //save the image
                StorageFolder folder = KnownFolders.SavedPictures;
                StorageFile capturefile = await folder.CreateFileAsync("photo_" + DateTime.Now.Ticks.ToString() + ".jpg", CreationCollisionOption.ReplaceExisting);
                captureFileName = capturefile.Name;

                //store stream in file
                using (var fileStream = await capturefile.OpenStreamForWriteAsync())
                {
                    try
                    {
                        //because of using statement stream will be closed automatically after copying finished
                        await RandomAccessStream.CopyAsync(imageStream, fileStream.AsOutputStream());
                    }
                    catch 
                    {

                    }
                }
            }

Of course, we need to stop the preview after we captured the photo. It also makes all sense to load the saved image and display it to the user. This is the code to stop the preview:

        private async void CleanCapture()
        {

            if (captureManager != null)
            {
                if (isPreviewing == true)
                {
                    await captureManager.StopPreviewAsync();
                    isPreviewing = false;
                }
                captureManager.Dispose();

                previewElement.Source = null;
                previewElement.Visibility = Visibility.Collapsed;
                takenImage.Source = null;
                takenImage.Visibility = Visibility.Collapsed;
                captureButton.Content = "capture";
            }

        }

The result of above mentioned code (screenshot of preview left, captured photo right):

16by9Photo

Cropping the captured photo

Not all Windows Phone devices have an aspect ratio of 16:9. In fact, most devices in the market have an aspect ratio of 15:9, due to the fact that they are WVGA or WXGA devices (I talked a bit about this already in my second post). If we are just capturing the photo with the method above, we will have the same black bands in our image as we have in our preview. To get around this and capture a photo that has a true 15:9 resolution (makes sense for photos that get reused in apps, but less for real life photos), additional code is needed.

As with getting the right camera solution, I generated an Enumeration that holds all possible values as well as a helper method to detect which aspect ratio the currently used device has:

        public enum DisplayAspectRatio
        {
            Unknown = -1,

            FifteenByNine = 0,

            SixteenByNine = 1
        }

        private DisplayAspectRatio GetDisplayAspectRatio()
        {
            DisplayAspectRatio result = DisplayAspectRatio.Unknown;

            //WP8.1 uses logical pixel dimensions, we need to convert this to raw pixel dimensions
            double logicalPixelWidth = Windows.UI.Xaml.Window.Current.Bounds.Width;
            double logicalPixelHeight = Windows.UI.Xaml.Window.Current.Bounds.Height;

            double rawPerViewPixels = DisplayInformation.GetForCurrentView().RawPixelsPerViewPixel;
            double rawPixelHeight = logicalPixelHeight * rawPerViewPixels;
            double rawPixelWidth = logicalPixelWidth * rawPerViewPixels;

            //calculate and return screen format
            double relation = Math.Max(rawPixelWidth, rawPixelHeight) / Math.Min(rawPixelWidth, rawPixelHeight);
            if (Math.Abs(relation - (15.0 / 9.0)) < 0.01)
            {
                result = DisplayAspectRatio.FifteenByNine;
            }
            else if (Math.Abs(relation - (16.0 / 9.0)) < 0.01)
            {
                result = DisplayAspectRatio.SixteenByNine;
            }

            return result;
        }

In Windows Phone 8.1, all Elements use logical pixel size. To get the values that most of us are used to, we need to calculate the raw pixels from the logical pixels. After that, we use the same math operations I used already for detecting the ratio of the camera resolution (see post 2). I tried to calculate the values with the logical pixels as well, but this ended up in some strange rounding behavior and not the results I wanted. That’s why I use the raw pixel sizes.

Before we continue with capturing the photo, we are going to add a border that is displayed and shows the area which is captured to the user in XAML:

            

When we are cropping our photo, we need to treaten the BitmapEncoder and the BitmapDecoder separately. To crop an image, we  need to set the Bounds and the new Width and Height of the photo via the BitmapTransform.Bounds property. We also need to read the PixelData via the GetPixelDataAsync() method, apply the changed Bounds to it and pass them to BitmapEncoder via the SetPixelData() method.

At the end, we are flushing the changed stream data directly into the file stream of our StorageFile. Here is how:

            //declare string for filename
            string captureFileName = string.Empty;
            //declare image format
            ImageEncodingProperties format = ImageEncodingProperties.CreateJpeg();

            using (var imageStream = new InMemoryRandomAccessStream())
            {
                //generate stream from MediaCapture
                await captureManager.CapturePhotoToStreamAsync(format, imageStream);

                //create decoder and transform
                BitmapDecoder dec = await BitmapDecoder.CreateAsync(imageStream);
                BitmapTransform transform = new BitmapTransform();

                //roate the image
                transform.Rotation = BitmapRotation.Clockwise90Degrees;
                transform.Bounds = GetFifteenByNineBounds();

                //get the conversion data that we need to save the cropped and rotated image
                BitmapPixelFormat pixelFormat = dec.BitmapPixelFormat;
                BitmapAlphaMode alpha = dec.BitmapAlphaMode;

                //read the PixelData
                PixelDataProvider pixelProvider = await dec.GetPixelDataAsync(
                    pixelFormat,
                    alpha,
                    transform,
                    ExifOrientationMode.RespectExifOrientation,
                    ColorManagementMode.ColorManageToSRgb
                    );
                byte[] pixels = pixelProvider.DetachPixelData();

                //generate the file
                StorageFolder folder = KnownFolders.SavedPictures;
                StorageFile capturefile = await folder.CreateFileAsync("photo_" + DateTime.Now.Ticks.ToString() + ".jpg", CreationCollisionOption.ReplaceExisting);
                captureFileName = capturefile.Name;

                //writing directly into the file stream
                using (IRandomAccessStream convertedImageStream = await capturefile.OpenAsync(FileAccessMode.ReadWrite))
                {
                    //write changes to the BitmapEncoder
                    BitmapEncoder enc = await BitmapEncoder.CreateAsync(BitmapEncoder.JpegEncoderId, convertedImageStream);
                    enc.SetPixelData(
                        pixelFormat,
                        alpha,
                        transform.Bounds.Width,
                        transform.Bounds.Height,
                        dec.DpiX,
                        dec.DpiY,
                        pixels
                        );

                    await enc.FlushAsync();
                }
            }

You may have notice the GetFifteenByNineBounds() method in the above code. As we need to calculate some values for cropping the image, I decided to separate them. They are not only providing values for the image to be cropped, but also size values for our earlier added Border that is used in my sample (download link at the end of the project) to show the size that the photo will have after our cropping (which is an automatic process in our case,). Here is the code:

        private BitmapBounds GetFifteenByNineBounds()
        {
            BitmapBounds bounds = new BitmapBounds();

            //image size is raw pixels, so we need also here raw pixels
            double logicalPixelWidth = Windows.UI.Xaml.Window.Current.Bounds.Width;
            double logicalPixelHeight = Windows.UI.Xaml.Window.Current.Bounds.Height;

            double rawPerViewPixels = DisplayInformation.GetForCurrentView().RawPixelsPerViewPixel;
            double rawPixelHeight = logicalPixelHeight * rawPerViewPixels;
            double rawPixelWidth = logicalPixelWidth * rawPerViewPixels;

            //calculate scale factor of UniformToFill Height (remember, we rotated the preview)
            double scaleFactorVisualHeight = maxResolution().Width / rawPixelHeight;

            //calculate the visual Width
            //(because UniFormToFill scaled the previewElement Width down to match the previewElement Height)
            double visualWidth = maxResolution().Height / scaleFactorVisualHeight;
            
            //calculate cropping area for 15:9
            uint scaledBoundsWidth = maxResolution().Height;
            uint scaledBoundsHeight = (scaledBoundsWidth / 9) * 15;

            //we are starting at the top of the image
            bounds.Y = 0;
            //cropping the image width
            bounds.X = 0;
            bounds.Height = scaledBoundsHeight;
            bounds.Width = scaledBoundsWidth;

            //set finalPhotoAreaBorder values that shows the user the area that is captured
            finalPhotoAreaBorder.Width = (scaledBoundsWidth / scaleFactorVisualHeight) / rawPerViewPixels;
            finalPhotoAreaBorder.Height = (scaledBoundsHeight / scaleFactorVisualHeight) / rawPerViewPixels;
            finalPhotoAreaBorder.Margin = new Thickness(
                                            Math.Floor(((rawPixelWidth - visualWidth) / 2) / rawPerViewPixels), 
                                            0,
                                            Math.Floor(((rawPixelWidth - visualWidth) / 2) / rawPerViewPixels), 
                                            0);
            finalPhotoAreaBorder.Visibility = Visibility.Visible;

            return bounds;
        }

Again, we need to apply raw pixels to achieve the best results here (I just pasted those lines in for this sample). To calculate the correct values for our Border, we need the scale factor between the screen and the preview resolution we used (which is the scaleFactorVisualHeight double).  Before we’re calculating the border values, we are setting the Width to resolution’s Height (we rotated, remember?) and calculate the matching 15:9 Height.

The Border values are based on the Width and Height of the cropped image, but scaled down by scaleFactorVisualHeight’s value and converted in raw pixel. The Margin positions the border accordingly on top of the preview element.

This is the result of above mentioned code (screenshot of preview left, captured photo right):

15by9Photo

That’s all you need to know to get started with basic photo capturing from within your Windows Phone 8.1 Runtime app. Of course, there are also other modifications that you can apply, and I mentioned already most of the classes that lead you to the matching methods and properties (click on the links to get to the documentation)

By the way, most of the code can be adapted in a Windows 8.1 app as well (with some differences, of course).

Sample project

As promised, you can download the sample here. It contains all code snippets I showed you and is able to run as you build and deploy it.

As always, feedback is welcome and I hope this post is helpful for some of  you.

Until the next time, happy coding!

Posted by msicc in Dev Stories, win8dev, wpdev, 21 comments

How to capture a photo in your Windows Phone 8.1 Runtime app-Part II: some common modifications

Like promised in my first post about photo capturing, I will provide some common modification scenarios when using the MediaCapture API. This is what this post is about.

Choosing a camera

If you read my first post, you probably remember that the MediaCapture API automatically selected the front camera of my Lumia 1020. Like often, we have to write some additional code to switch between the cameras.

The cameras are listed in the Panels in the Windows.Devices.Enumeration Namespace. This namespace contains all “devices” that are connected to the phone and has different properties to detect the correct panel. We are going to use the DeviceClass to detect all video capture devices (which are normally also the photo capture devices on Windows Phone, but can be different on a PC/Tablet). As we want to switch between Front and Back, we are also detecting the EnclosureLocation. Here is how I implemented it:

        private static async Task<DeviceInformation> GetCameraID(Windows.Devices.Enumeration.Panel camera)
        {
            DeviceInformation deviceID = (await DeviceInformation.FindAllAsync(DeviceClass.VideoCapture))
                .FirstOrDefault(x => x.EnclosureLocation != null && x.EnclosureLocation.Panel == camera);

            return deviceID;
        }

To make this Task actually useful, we are also updating the InitializePreview() method from the first part:

        private async void InitializePreview()
        {
            captureManager = new MediaCapture();

            var cameraID = await GetCameraID(Windows.Devices.Enumeration.Panel.Back);

            await captureManager.InitializeAsync(new MediaCaptureInitializationSettings
            {
                StreamingCaptureMode = StreamingCaptureMode.Video,
                PhotoCaptureSource = PhotoCaptureSource.Photo,
                AudioDeviceId = string.Empty,
                VideoDeviceId = cameraID.Id,
            });

            StartPreview();
        }

In this case, we  selected the back camera. To make the MediaCapture API actually use this device, we need to generate a new instance of MediaCaptureInitializationSettings, where we select the cameras Id as VideDeviceId. If you now start capturing, this is an exemplary result:

wp_ss_20141115_0001

Rotating the preview

However, this not quite satisfying, because the preview automatically uses the landscape orientation. Luckily, this can be changed with just one single line of code (that needs to be added before actually starting the preview):

captureManager.SetPreviewRotation(VideoRotation.Clockwise90Degrees);

Now the result looks like this:

wp_ss_20141115_0002

Note: the black bands on both sides may happen due to the fact that most devices have a 15:9 ratio (WXGA, WVGA). On Devices like the Lumia 830 or 930, which have a 16:9 ratio, the preview will use the full screen in portrait mode. I tried a lot of things to get rid of those bands already, sadly without success. Once I found a proper solution, I will write another blog post and link it here on how to do it (any tips are welcome).

Limiting resolution

Sometimes, we need to limit resolutions (for example resolution limits on other parts in our app). This is possible by detecting the supported solutions and matching them to the screen ratio. As we are using the whole screen for previewing, of course we want to get our captured photo to use the same space, too.

My way to do this is to calculate the screen ratio, and return an enumeration value. This is the easiest way, and can be easily used in the further code to limit the resolution. The enumeration looks like this:

public enum CameraResolutionFormat
{
    Unknown = -1,

    FourByThree = 0,

    SixteenByNine = 1
}

And this is my helper to match the screen format (which is always wide screen on Windows Phone):

        private CameraResolutionFormat MatchScreenFormat(Size resolution)
        {
            CameraResolutionFormat result = CameraResolutionFormat.Unknown;

            double relation = Math.Max(resolution.Width, resolution.Height) / Math.Min(resolution.Width, resolution.Height);
            if (Math.Abs(relation - (4.0 / 3.0)) < 0.01)
            {
                result = CameraResolutionFormat.FourByThree;
            }
            else if (Math.Abs(relation - (16.0 / 9.0)) < 0.01)
            {
                result = CameraResolutionFormat.SixteenByNine;
            }

            return result;
        }

We could easily extend the calculation to 15:9, too. However, as the most camera resolutions are 4:3 or 16:9, this makes no sense in our use case (as 15:9 is still a widescreen format). The next thing we need to add is another helper to get the highest possible resolution for our photo and the preview. We are achieving this by generating a new object of type VideoEncodingProperties:

        private VideoEncodingProperties maxResolution()
        {
            VideoEncodingProperties resolutionMax = null;

            //get all photo properties
            var resolutions = captureManager.VideoDeviceController.GetAvailableMediaStreamProperties(MediaStreamType.Photo);

            //generate new list to work with
            List<VideoEncodingProperties> vidProps = new List<VideoEncodingProperties>();

            //add only those properties that are 16:9 to our own list
            for (var i = 0; i < resolutions.Count; i++)
            {
                VideoEncodingProperties res = (VideoEncodingProperties)resolutions[i];

                if (MatchScreenFormat(new Size(res.Width, res.Height)) != CameraResolutionFormat.FourByThree)
                {
                    vidProps.Add(res);
                }
            }

            //order the list, and select the highest resolution that fits our limit
            if (vidProps.Count != 0)
            {
                vidProps = vidProps.OrderByDescending(r => r.Width).ToList();

                resolutionMax = vidProps.Where(r => r.Width < 2600).First();                
            }

            return resolutionMax;
        }

What I am doing here: I read all available VideoEncodingProperties for the MediaStreamType Photo. As I mentioned before, we need only wide screen resolution for Windows Phone, that’s why I add only those that have not a 4:3 ratio to my list. Then I am using LINQ to order the list and select the highest resolution from that list.

Using this helper is also very easy, done with one line of code before starting the preview and best also before rotating the preview:

await captureManager.VideoDeviceController.SetMediaStreamPropertiesAsync(MediaStreamType.Photo, maxResolution());

This way, we are able to respect any resolution limits that we might face while developing our app, while keeping the photo quality as high as possible.

        private CameraResolutionFormat MatchScreenFormat(Size resolution)
        {
            CameraResolutionFormat result = CameraResolutionFormat.Unknown;

            double relation = Math.Max(resolution.Width, resolution.Height) / Math.Min(resolution.Width, resolution.Height);
            if (Math.Abs(relation - (4.0 / 3.0)) < 0.01)
            {
                result = CameraResolutionFormat.FourByThree;
            }
            else if (Math.Abs(relation - (16.0 / 9.0)) < 0.01)
            {
                result = CameraResolutionFormat.SixteenByNine;
            }

            return result;
        }

Focus

Focusing on objects in your photo is quite important. Sadly, it seems that currently we are not able to have a one solution fits all devices solution for using AutoFocus. I experimented a lot with it, and finally I got aware of known issues with Nokia drivers and the new MediaCapture API’s, as described here. Microsoft is working with Nokia (or their devices department) to fix this problem.

The only solution I got working for an Runtime app is to use manual focus. All other attempts gave me one Exception after the other, be it on cancelling the preview or be it on while previewing itself.  I’ll write another post on how to use the AutoFocus as soon as it is working like it should. In the meantime, here is my solution for manual focusing.

First, add a Slider control in your XAML page:

<Slider x:Name="FocusValueSlider" Maximum="1000" Minimum="0" Grid.Row="0" Margin="12,0,15,0" Header="adjust focus:" ValueChanged="FocusValueSlider_ValueChanged" Value="500" SmallChange="25" LargeChange="100" ></Slider>

Notice that as with any slider, you need to follow the order: Set Maximum first, then Minimum. If you do not, you will likely get an unusable Slider in return. If the VideoDeviceController.Focus property would work (seems like it is also affected by the above mentioned driver problems), we could read and set the Slider values from its MediaDeviceControl.Capabilities property. I tried to read them at any stage of previewing, but their values are always 0.0, null and false. The range up to 1000 fits in very well on all devices I tested (Lumia 920, 930 and 1020).

Ok, enough of whining. Let’s have a look at my solution. First, we need to generate a small helper that allows us to adjust the focus based on the slider values:

        private async void SetFocus(uint? focusValue = null)
        {
            //try catch used to avoid app crash at startup when no CaptureElement is active
            try
            {
                //setting default value
                if (!focusValue.HasValue)
                {
                    focusValue = 500;
                }

                //check if the devices camera supports focus control
                if (captureManager.VideoDeviceController.FocusControl.Supported)
                {
                    //disable flash assist for focus control
                    captureManager.VideoDeviceController.FlashControl.AssistantLightEnabled = false;

                    //configure the FocusControl to manual mode
                    captureManager.VideoDeviceController.FocusControl.Configure(new FocusSettings() { Mode = FocusMode.Manual, Value = focusValue, DisableDriverFallback = true });
                    //update the focus on our MediaCapture
                    await captureManager.VideoDeviceController.FocusControl.FocusAsync();
                }
            }
            catch { }
        }

This methods checks if the current camera supports Focus, and sets its value according to the slider. The AssistantLight is disabled in this case. Its default is enabled (true).

To add the possibility to adjust the focus, we need to configure our own FocusSettings that tell the camera that we are focusing manually based on the slider’s value. Finally, we need to perform the focusing action by calling the FocusControl’s FocusAsync method.

The next step is to hook up to changes in the slider values within the FocusValueSlider_ValueChanged event:

        private void FocusValueSlider_ValueChanged(object sender, RangeBaseValueChangedEventArgs e)
        {
            try
            {
                //convert double e.NewValue to uint and call SetFocus()
                uint focus = Convert.ToUInt32(e.NewValue);
                SetFocus(focus);
            }
            catch 
            {
                
            }
        }

Now every move of the slider will change the focus of the preview and of course also of the captured photo (which we will learn more about in the third post of this series).  To initialize our Focus correctly with the value of 500 we set in XAML, just call SetFocus(); before you start the preview. Here is the result:

focus screenshot

 

Disclaimer: I do not know if this follows best practices, but it works. If you have feedback for the above mentioned code snippets, feel free to leave a comment below.

In the third and last post I’ll show you how to save the images (also in different folders or only within the app).

Until then, happy coding!

Posted by msicc in Dev Stories, win8dev, wpdev, 9 comments