Not long ago, Microsoft released its new device, the Surface Studio, a powerhorse with a 28” touch screen, with characteristics that make it a go in the wish list for every geek (https://www.microsoft.com/en-us/surface/devices/surface-studio/overview).

With it, Microsoft released the Surface Dial, a rotary wheel that redefines the way you work when you are doing some creative design (https://www.microsoft.com/en-us/surface/accessories/surface-dial). Although it was created to interact directly with the Surface Studio (you can put it on the screen and it will open new ways to work, you can also use it even if you don’t have the Surface Studio.

In fact, you can use it with any device that has bluetooth connection and Windows 10 Anniversary edition. This article will show you how to use the Surface Dial in a UWP application and enhance the ways your user can interact with your app.

Working with the Surface Dial

Work with the Surface Dial is very easy. Just open the “Manage Bluetooth Devices” window and, in the Surface Dial, open the bottom cover to show the batteries and press the button there until the led starts blinking. The Surface Dial will appear in the window:

image

Just click on it and select “Connect”. Voilà, you are ready to go. And what can you do, now? Just out of the box, many things:

  • Go to a browser window and turn the wheel, and you’ll start scrolling the page content
  • Click on the dial and a menu opens:

image

If you turn the wheel, you can change the function the wheel does:

  • Volume, to increase or decrease the sound volume of you machine
  • Scroll, to scroll up and down the content (the default setting)
  • Zoom, to zoom in and out
  • Undo, to undo or redo the last thing

The best thing here is that it works in the program you are in, no matter if it’s a Windows 10 program or no (for example, you can use it for Undo/Redo in Word or to scroll in the Chrome browser). All of this comes for free, you don’t have to do anything.

If you want to give an extra usability for your Surface Dial, you can go to Windows Settings/Devices/Wheel and set new tools for your apps. For example, if you have a data entry form and you want to move between the text boxes, you can create a Custom Tool like this:

image

That way, the user will be able to move between the boxes using the Surface Dial. Nice, no?

But what if you want to create a special experience for your user? We’ll do that now, creating a UWP program that will be able to change properties of a rectangle: change its size, position, angle or color, with just one tool: the Surface Dial.

Creating a UWP program for the Surface Dial

Initially, let’s create a UWP program in Visual Studio. You must target the Anniversary Edition. If you don’t have it, you must install Visual Studio Update 3 on your system.

Then, add the rectangle to MainPage.xaml:

<Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
    <Rectangle Width="100" Height="100" Fill =" Red" x:Name="Rectangle" RenderTransformOrigin="0.5,0.5">
        <Rectangle.RenderTransform>
            <TransformGroup>
                <ScaleTransform x:Name="Scale" ScaleX="1"/>
                <RotateTransform x:Name="Rotate" Angle="0"/>
                <TranslateTransform x:Name="Translate" X="0" Y="0"/>
            </TransformGroup>
        </Rectangle.RenderTransform>
    </Rectangle>
</Grid>

We have added a RenderTransform to the rectangle, so we can scale, rotate or translate it later with the Surface Dial.

The next step is add some png files for the Surface Dial icons. Get some Pngs that represent Rotate, Resize, Move in X Axis, Move in Y Axis and Change Colors (I’ve got mine from https://www.materialui.co) and add them to the Assets folder in the project.

In MainPage.xaml.cs, get the Dial controller, initialize the Surface Dial menu and set its RotationChanged event handler:

public enum CurrentTool
{
    Resize,
    Rotate,
    MoveX,
    MoveY,
    Color
}

private CurrentTool _currentTool;
private readonly List<SolidColorBrush> _namedBrushes;
private int _selBrush;

public MainPage()
{
    this.InitializeComponent();
    // Create a reference to the RadialController.
    var controller = RadialController.CreateForCurrentView();

    // Create the icons for the dial menu
    var iconResize = RandomAccessStreamReference.CreateFromUri(new Uri("ms-appx:///Assets/Resize.png"));
    var iconRotate = RandomAccessStreamReference.CreateFromUri(new Uri("ms-appx:///Assets/Rotate.png"));
    var iconMoveX= RandomAccessStreamReference.CreateFromUri(new Uri("ms-appx:///Assets/MoveX.png"));
    var iconMoveY = RandomAccessStreamReference.CreateFromUri(new Uri("ms-appx:///Assets/MoveY.png"));
    var iconColor = RandomAccessStreamReference.CreateFromUri(new Uri("ms-appx:///Assets/Color.png"));

    // Create the items for the menu
    var itemResize = RadialControllerMenuItem.CreateFromIcon("Resize", iconResize);
    var itemRotate = RadialControllerMenuItem.CreateFromIcon("Rotate", iconRotate);
    var itemMoveX = RadialControllerMenuItem.CreateFromIcon("MoveX", iconMoveX);
    var itemMoveY = RadialControllerMenuItem.CreateFromIcon("MoveY", iconMoveY);
    var itemColor = RadialControllerMenuItem.CreateFromIcon("Color", iconColor);

    // Add the items to the menu
    controller.Menu.Items.Add(itemResize);
    controller.Menu.Items.Add(itemRotate);
    controller.Menu.Items.Add(itemMoveX);
    controller.Menu.Items.Add(itemMoveY);
    controller.Menu.Items.Add(itemColor);

    // Select the correct tool when the item is selected
    itemResize.Invoked += (s,e) =>_currentTool = CurrentTool.Resize;
    itemRotate.Invoked += (s,e) =>_currentTool = CurrentTool.Rotate;
    itemMoveX.Invoked += (s,e) =>_currentTool = CurrentTool.MoveX;
    itemMoveY.Invoked += (s,e) =>_currentTool = CurrentTool.MoveY;
    itemColor.Invoked += (s,e) =>_currentTool = CurrentTool.Color;

    // Get all named colors and create brushes from them
    _namedBrushes = typeof(Colors).GetRuntimeProperties().Select(c => new SolidColorBrush((Color)c.GetValue(null))).ToList();
    
    controller.RotationChanged += ControllerRotationChanged;
    
    // Leave only the Volume default item - Zoom and Undo won't be used
    RadialControllerConfiguration config = RadialControllerConfiguration.GetForCurrentView();
    config.SetDefaultMenuItems(new[] { RadialControllerSystemMenuItemKind.Volume });

}

The first step is to get the current controller with RadialController.CreateForCurrentView(). Then, create the icons, initialize the items and add them to the menu. For each item, there will be an Invoked event that will be called when the menu item is invoked. At that time, we select the tool we want. The last steps are to set up the RotationChanged event handler and to remove the default menu items we don’t want.

The RotationChanged event handler is

private void ControllerRotationChanged(RadialController sender, RadialControllerRotationChangedEventArgs args)
{
    switch (_currentTool)
    {
        case CurrentTool.Resize:
            Scale.ScaleX += args.RotationDeltaInDegrees / 10;
            Scale.ScaleY += args.RotationDeltaInDegrees / 10;
            break;
        case CurrentTool.Rotate:
            Rotate.Angle += args.RotationDeltaInDegrees;
            break;
        case CurrentTool.MoveX:
            Translate.X += args.RotationDeltaInDegrees;
            break;
        case CurrentTool.MoveY:
            Translate.Y += args.RotationDeltaInDegrees;
            break;
        case CurrentTool.Color:
            _selBrush += (int)(args.RotationDeltaInDegrees / 10);
            if (_selBrush >= _namedBrushes.Count)
                _selBrush = 0;
            if (_selBrush < 0)
                _selBrush = _namedBrushes.Count-1;
            Rectangle.Fill = _namedBrushes[(int)_selBrush];
            break;
        default:
            break;
    }
    
}

Depending on the tool we have, we work with the desired transform. For changing colors, I’ve used an array of brushes, created from the named colors in the system. When the user rotates the dial, I select a new color in the array.

Now, when you run the program, you have something like this:

image

Conclusions

As you can see, we’ve created a completely new interaction for the user. Now, he can change size, angle, position or even color with the dial, without having to select things with the mouse. That’s really a completely new experience and that can be achieved just with a few lines of code. With the Surface Dial you can give to your users a different experience, even if they are not using the Surface Studio.

The full source code for the project is at https://github.com/bsonnino/SurfaceDial.

2016 is coming to an end (What an year here in Brazil!), and we can see retrospectives everywhere. I don’t want to do a “What happened”  or “What did I do”  retrospective. Instead, I want to write about the open source projects I used along the year.

I use open source projects a lot (I don’t like to reinvent the wheel) and they help me a lot. Although many open source projects have a lot of collaborators, most of the time, they are an effort of a single developer (or a very small group of developers) that spend their own spare time to release these gems to the public, without asking anything in return (yes – they are a case of free as “free beer” and free as “freedom”). Nothing more fair than write some lines about them as a way to say “thank you”. So let’s go!

Microsoft open source projects

In the latest years, Microsoft released a lot of open source projects: Roslyn, .NET Core, Asp.NET core, Reactive Extensions, VSCode, TypeScrypt, SignalR and PowerShell are just some of the projects that can be cloned and modified as you will (do you know that Microsoft has the largest number of open source contributors to GitHub: http://www.networkworld.com/article/3120774/open-source-tools/microsoft-s-the-top-open-source-contributor-on-github.html ?).

Although releasing the core projects is something new, I’ve been using Microsoft open source code for a long time – when I started developing, their sample projects were the best way to learn how to use the technology, and this is already the case. If you haven’t checked, go to the Microsoft samples (https://github.com/Microsoft/Windows-universal-samples) to check how to use the newest technology for Windows 10.

So, the first in this retrospective is Microsoft – you can check its open source projects in https://opensource.microsoft.com/ (there were 193 projects there at the time) and in their GitHub: https://github.com/Microsoft (there were 42 pages of repositories there!).

MVVM Light

If you develop for any of the XAML technologies and don’t use the MVVM pattern, shame on you! You should be using this pattern, as it eases the separation between business rules and UI,  facilitates testing and enhances maintainability of your code.

The pattern is very easy to implement and you don’t need any special framework to use it, but using a framework will make things easier and enforce some good rules for your code. There are several MVVM frameworks out there (MVVM Light, Caliburn Micro, Calcium, MVVM Cross, Prism are some that come to my mind, now – maybe I can add to write an article about them – this can be on my resolutions for 2017 Smile), but the one I use the most is MVVM Light Toolkit (http://www.mvvmlight.net/ , source code at http://mvvmlight.codeplex.com/), a nice work from Laurent Bugnion, an old time MVP from Switzerland.

This framework is very easy to use, you must create your ViewModels derived from ViewModelBase and, when you need a command binding, you can use the RelayCommand class. For communication between ViewModels and Views, you can use the Messenger class for sending messages between them. There is a simple IoC container, so you can use dependency injection in your code (another nice feature to remove coupling).

The simplicity and ease of use is definitely a big plus in this framework and the only thing I can say now is “Thanks, Laurent” !

Json.NET

If you are adding Nuget packages to your project, this is the first project that appears in the list. If you need to process Json data (and most developers need it), you must use this project. It’s a high performance Json package and it’s even included in the template for a new Asp.Net project!

It is mainly developed by James Newton-King and you can find it in http://www.newtonsoft.com/json (source code at https://github.com/JamesNK/Newtonsoft.Json). It has a very good Json serializer/deserializer and you can even use Linq to process the Json data. If you want to see it in use, take a look at my article http://blogs.msmvps.com/bsonnino/2016/05/26/minifying-and-formatting-json-data-with-c/ or check my Json Minifier project at https://github.com/bsonnino/ProcessJson.

LightInject

There are many open source IoC containers frameworks out there, and I like very much SimpleInjector, Unity and Ninject, but the one I use most is LightInject (http://www.lightinject.net , source code at https://github.com/seesharper/LightInject), a framework developed by Bernhard Richter. It’s very fast and lightweight and it works on most platforms I use to develop. It works fine with the IoC container available in MVVM Light, and you have several ways to resolve your dependencies.

I really recommend using an IoC container to break your dependencies and make your code more robust. Although it takes some time to get used to this kind of programming, it certainly pays it off when it comes to reusing code and debugging it.

FakeItEasy

Testing, oh, Testing! Testing is like flossing – everybody knows that they should do it, but very few (I would say nobody, but that would not be fair to some poor souls) really do it. When it comes to testing, I really think that one of the worst parts is to mock objects for the tests: create fake classes that do some fake behavior seems to me like some sin I am doing – I should not be doing that or I will go to hell.

FakeItEasy (https://fakeiteasy.github.io/ , source code at https://github.com/FakeItEasy/FakeItEasy) relieves me from that sin. With it, I am able to mock objects and create behaviors that simulate what I want in my tests. The quantity of source code this library saves me is really huge! Oh, and besides all the documentation you have for it, you can also have a free book, published by Syncfusion (one other thing I really recommend – their Succinctly series, now with 103 free ebooks, have fast documentation about a number of subjects: https://www.syncfusion.com/resources/techportal/ebooks): https://www.syncfusion.com/resources/techportal/details/ebooks/fakeiteasy. The only thing I regret in this library is the lack of support for faking under Windows 8 or Windows 10 (In this case, I have to try the LightMock library and see if it fits – another resolution for 2017).

HtmlAgilityPack

By the name, you can think that this pack is for use in an ASP.NET program, but this is not the case. This framework parses HTML files, and you can use it in any .NET application. It’s wonderful when you want to do some web scraping: just load your HTML file into an HtmlDocument and you can easily get the data in it – you can parse the HTML and even change the data in it.

You can get this package at https://htmlagilitypack.codeplex.com/

DotNetZip

If you need to manipulate Zip files in a .NET program, you can use DotNetZip (https://dotnetzip.codeplex.com/). With it, you can open zip files and add new files to them, extract or list the contents of a zip. You can even use Linq to query for entries you want. The files can have password encryption, and it also supports Zip64.

MetroLog

Logging is something that I always need for my programs. When it comes to UWP, there are not many options out there. One of them is Metrolog (https://github.com/onovotny/MetroLog), a very lightweight logging framework developed by Oren Novotny, that works fine with Windows 8/8.1 or UWP.

Although lightweight, it has many features, you can configure the destination of the logs, the logging format and it’s very easy to use: just configure the logging and get a logger with LogManagerFactory.GetDefaultLogger and you can start logging. 

UWPCommunityToolkit

Although this project is under the Microsoft Github (https://github.com/Microsoft/UWPCommunityToolkit, website at https://developer.microsoft.com/en-us/windows/uwp-community-toolkit), it’s not entirely developed by Microsoft. This is a set of components developed by community developers and Microsoft employees, and  features a set of components that are not in the UWP SDK.

You get there a set of controls, like  the Hamburger menu, a Radial gauge or a listview with the “pull to refresh”, many new animations, some code helpers, like new converters or storage helpers, or even access to services like Bing, Facebook or Twitter.

This set of components can improve your UWP apps with minimal code, it’s highly recommended.

SQLite.Net

If you need some kind of structured storage in a UWP application, the best way to do it is using a Sqlite database. In this case, you should use Sqlite.NET (https://github.com/praeclarum/sqlite-net), a small ORM for SQLite databases.

It’s very easy to use and you can have a very good database to store your data in a UWP app, without having to resort to database commands. I really like ORMs, as they abstract the use of a database and use normal C# classes to store data. When you are using a local SQLite database, this ORM is really nice!

Trinet.Core.IO.Ntfs

You won’t be using this library very often, but if you want to handle Alternate Data Streams, like I did in my article here, the Trinet.Core.IO.Ntfs (https://www.codeproject.com/Articles/2670/Accessing-alternative-data-streams-of-files-on-an , source code at https://github.com/hubkey/Trinet.Core.IO.Ntfs) will help you, without the need of adding P/Invokes and working with the Win32 API.

You can check its use in my article and take a look at the ADSs in your system (it surely worth to see what’s hidden in your files).

WPFFolderBrowser

One missing component in WPF is the Folder Browser. Usual answers to this item is to add System.Windows.Forms as a reference to your project and use the Windows Forms component in the program. That’s something I really don’t like: why should I add Windows Forms to my WPF project if I don’t want to use it?

With the Vista Bridge project (now the Windows API Code Pack – https://blogs.msdn.microsoft.com/windowssdk/2009/06/12/windows-api-code-pack-for-microsoft-net-framework/), there were a lot of components that made the bridge between the Windows 32 API released by Vista and WPF.

WPFFolderBrowser (http://wpffolderbrowser.codeplex.com/) takes the work in The Code Pack and creates a Folder Browser for WPF without having to use Windows Forms.

WriteableBitmapEx

Did you ever had the need to create a bitmap from scratch? Or to take a bitmap and change it? WriteableBitmapEx (https://github.com/teichgraf/WriteableBitmapEx/) is a library to manipulate bitmaps. It extends WriteableBitmaps and adds more processing to the bitmap manipulation.

It’s really fast and easy to use, and if you need to do something with a bitmap, you should really use it.

PCLCrypto

Cryptography is something that is needed in your apps from time to time. Windows 8/8.1 and UWP have cryptographic functions that work very well, but, if you need to have portable functions between UWP and full .NET (WPF, Windows Forms or ASP.NET), you should try PCLCrypto (https://github.com/AArnott/PCLCrypto), that uses façade assemblies to the real implementations in every platform.

This way, you use the native cryptographic assemblies for every platform without having to resort to conditional compilation.

Callisto

Callisto (https://timheuer.github.io/callisto/ , source at https://github.com/timheuer/callisto) is a framework developed by Tim Heuer, a Microsoft Program Manager, and was very useful for Windows 8 apps, especially when there was no Flyout control – at that time, the best way to implement it was to use Callisto.

Now, that a Flyout control is in the SDK, there are still a lot to use in Callisto: the rating control, the numeric up/down and the custom dialog are just some I use normally. If you haven’t checked it, it’s worth giving a look at it.

Conclusions

There was a lot covered here. As you can see, I use open source a lot, and I know it’s a big effort to maintain these libraries up-to date, so I’d like to thank all the developers that maintain these libraries and release them as open source, in a way that anybody can analyze them and use them as source code examples, use them to improve their apps without asking anything in return.

And you, do you have any other library that you think it should be listed? Do you want to know more about any of these (maybe I can write an extra article about it)? If you have anything to comment, please place it in the comments section.

Introduction

On my developer work, there are some tools that make my job much easier and I use them on a daily basis and miss them when I go to a computer where I don’t have them. To create code, I think that there’s no better tool than Resharper (see my article about it here). For debugging code, the equivalent is OzCode (http://oz-code.com/). I’ve been an OzCode user since its early betas (it was called BugAid, at those days), and it’s been improving from version to version, and its features are really valuable when debugging an app.

Using OzCode

When you are creating a program, you won’t see anything about OzCode, but as soon as you start debugging your program, OzCode appears and start to shine. One of my favorite features there is what they call Reveal (but I call this “Show me what I want”). Here’s the problem: if I have a list of items and I open it, all I see is something like this:

image

This is not what I want. As you can see, I have a list of 91 customers, and what is shown is the ToString evaluation of each one (“OzCodeTest.Customer”). I’d like to see what’s in each one of these customers and search for the ones I want. You may argue that I can create a ToString override and show what I want, but that is not intuitive, and I may change my mind while debugging (at the beginning I want to see the Id and Name, but in the middle of debugging I want to see the Name and City). And what about to find which one is located in London?

With OzCode, this is solved by simply opening one member and clicking on the star near it: the member is “favorited” and is shown in the list:

image

And what about searching? You just have to type in the search box and all items that match the search are shown:

image

If you want to create some special data, without having to create a new member, you can do so: just click on the magic wand besides the object and select “Add custom Expression”. Then, you can type the expression you want, and put the name of the new “member” after a double slash, like a comment:

[sourcecode language='csharp'  gutter='false']
[obj].City == “London” // IsFromLondon
[/sourcecode]

And it will appear on the list of members, where you can even make it as a favorite:

image

And if I only want to see the customers from London? Just click on the magic wand and select “Edit Filter”. Then, type the filter “[obj].City == “London””. The list of customers is filtered to show only the ones whose city is London:

image

One other thing that you can do here is to compare versions of the two lists: how many times do you need to know what changed between two points in the debugging? It’s very easy to find out. Just stop on the first point and click on the magic wand and select “Compare/Save value”. This will open a window to confirm. Confirm and continue running until the second point. Then click on the magic wand again and select “Compare/Compare with saved value”. A window appears and you can compare the two values. If you want to show only the differences, just click “Show differences only”:

image

Instant logging

The inspector window on steroids is very nice, but there is more help for our debugging. For me, it’s very common to need some logging in the code, to see what’s happening. I have to add a logging library, add code to log data and then analyze all logs in a separate tool. Too much work and sometimes I miss what I was expecting. So I must add a little more logging, repeat and rinse. Very cumbersome. With OzCode, all I have to do is to select the variable I’m interested, click on the yellow note icon that appears on the left and select Trace value of {variable}. That will add a new trace point that will log the value I’m interested to see.

 

image

When you run the program, you can see the number of messages traced in the bottom of the window, near the yellow note.

image

When you stop the program, you can see all messages sent in the Tracepoint viewer window:

image

There you can search for something, export the data to Excel, csv or text, so you can have a file to analyze later. Two nice features there are the Thread Id and the Stack trace. Often it’s difficult to debug multi-threading programs, when you go step by step, it’s difficult to follow the code, as the same code can be reached by different threads. If you click in the arrow next the thread Id, you will see from which threads this code was logged, and filter only some of them:

image

When you filter one thread, you can get only the messages that come from that thread:

image

The other thing that is nice is the stack trace. I always have the question: “How did the code reached here?”. The stack trace answers this:

image

Nice, no?

Swami sees all, the past and the future

If you take a look at the figure below, you will see a glimpse of the past and the future:

image

Just above line 16, you will see that we are working with the “ALFKI” customer. In line 18, you can see that the customer’s city is Berlin. OzCode will show you the following line dimmed – that line won’t be executed and the execution will go to line 20, where there is the arrow. You can also see that the second part of the If won’t be executed (it’s crossed out). You also can see the red X near the line, indicating it is false.

If you click on the glasses near the line, you will see more info:

image

You can have a lot of info about your data and how you reached there.

Exception handling

One thing that bothers me regarding exceptions is when I get an exception buried inside a bunch of Inner Exceptions. I must drill down the exception until I find something that is valuable. OzCode makes this a lot easier: when an exception is thrown, something like this one is shown:

image

You can see the exception that occurred above the line (in the code, above line 17), with four icons:

  • The first one will open the exception box – it is showing that there are two nested exceptions
  • The second one will toggle break in this kind of exception
  • The third one will go to the line where the exception occurred
  • The fourth one will search for help on Google, StackOverflow, Yahoo or Bing

If you click on the first icon or in the icon on the left of the line, it will open the exception box:

image

On the top, you will see a breadcrumb of the exception. You can click on any exceptions there and it will show you all the data for that exception and you can go to where the exception was thrown or where the exception was handled. You can also search for help in this window.

Another exception helper is the exception prediction. If you are stepping through code that will generate an exception, you get something like this:

image

You can click on the icon and skip the line, thus not throwing the exception or, if you are using Visual studio 2015, you can even edit the code and continue:

image

That’s really a great way to make your code more solid proof!

Conclusion

As you can see, OzCode gives you a lot of help for your debugging, I received a free copy due to the fact I’m a Microsoft MVP, but I really enjoy using it. If you want to try it by yourself, you can download a free version at http://oz-code.com. Happy debugging!

I’m sure that you have had this scenario at least once: you download a file from the internet and try to run it and it doesn’t work fine. If it is a CHM file, the help file doesn’t open the content:

image

 

If it’s an executable, it will show a message telling you that you got it from an unreliable source or, even worse, it stays there and does nothing. A client of mine set me a zip with some files to install. I downloaded the zip, unzipped it and tried to run and nothing happened. The only thing I could do is to open Task Manager and kill the Explorer process.

This is caused by a mechanism Windows has to lock files that come from the internet and can harm your computer. If it is a zipped file and you unzip it with Explorer, all extracted files will be protected with this mechanism. If you right click the file in Explorer, select Properties and check on the “Unlock” box, everything runs fine. The file is unlocked.

image

image

But what is this protection mechanism and how can we check if the file is protected and unprotect it?

The mechanism used is called “Alternate Data Streams” (ADS), and it’s a way that NTFS has to add extra data in a file. This data is not shown when you open a file and is size is not added to the total file size, but the data is there, hidden and taking disk space. If you open a command line prompt window and do a Dir /R command, you can see these alternate streams:

image

In the image above, you can see two lines for each file. The first one is the “real” file, and the second one is the “hidden” file. You can see that the “hidden” file has the same name of the “real” file and a complement after the colon. The Zone.Identifier:$DATA is the alternate stream for the file. It may have any name and can have any size (it can even be larger than the “real” file) and it’s a very effective way to hide information – if you open a file, you won’t see any trace of the alternate data stream. But, with great power comes great responsibility, and that can also be used for evil purposes – it can hide things the user is not aware and would not want in his computer.

For our blocked files, we know that they have a ADS, named Zone.Identifier. But what’s in the files? To show the contents of an ADS, you cannot use the normal tools. You can use Powershell to open them. For example, if you open a Powershell command line (se Window+X, then select “Windows Powershell”, you can type

Get-Content -Path .\Web_Servers_Succinctly.pdf -Stream Zone.Identifier

And it will show the contents of the file:

image

We can see that this file was transferred from Zone=3. From here we can see that 3 is URLZONE_INTERNET, the file came from the internet. So that’s what is blocking the file. It we unblock the file, here’s what we get when we query the streams in the file:

image

We have changed the ZoneId to 4, URLZONE_UNTRUSTED. This is enough to unblock the file.

Manipulating ADSs with C#

Now we know the mechanism behind Windows protection and we can create a C# program that unblocks all files in a directory. There is no API to access file streams in .NET, so you must resort to Win32 P/Invoke. The functions NtfsFindFirstStream and NtfsFindNextStream enumerate all streams in a file. DeleteFile will delete a stream, and CreateFile will create and add the stream.

Fortunately, we don’t have to work with this functions, as a brave developer has created a library to handle ADS in .NET (https://github.com/RichardD2/NTFS-Streams) and we can add it from Nuget. We will create a program to list, show contents or delete alternate streams with C#.

In Visual Studio, create a new Console application. Right click in the References node and select Manage Nuget Packages. There, install Trinet.Core.IO.Ntfs.

image

Then, in Program.cs, we will start to create our program:

static void Main(string[] args)
{
    if (args.Length == 0)
    {
        Console.WriteLine("usage: adsviewer -(l|s|d)  [streamname]");
        return;
    }
    var selSwitch = ProcessSwitches(args);
    if (selSwitch == null)
        return;
    var parameters = args.Where(a => !a.StartsWith("-"));
    string fileName = ".";
    if (parameters.Count() > 0)
        fileName = parameters.First();
    var streamName = parameters.Skip(1).FirstOrDefault();
    if (File.Exists(fileName))
        ProcessFile(fileName, streamName, selSwitch);
    else if (Directory.Exists(fileName))
        foreach (var file in Directory.GetFiles(fileName))
            ProcessFile(file, streamName, selSwitch);
    else
    {
        Console.WriteLine("error: file/folder does not exist");
        return;
    }
}

Initially, we’ve checked if the user passed any parameters. If not, we show the usage help. Then, we process the switch (the option with a hiphen), that can be a “l” (to list the stream names), a “s” (to show the content of the streams or a “d”  (to delete the streams.

Then, we get the file or folder name and the stream name. If the user didn’t pass any file name, we admit he wants to process all the streams in all files in the current directory. If he passes a name, we check if it’s a file or a folder. If it’s a folder, we will process all files in that folder.

If the user passes a stream name, we will only process that stream. If he doesn’t pass a name, we will process all streams in the file.

ProcessSwitches checks the passed switch and sees if its valid:

private static string ProcessSwitches(string[] args)
{
    var switches = args.Where(a => a.StartsWith("-"));
    if (switches.Count() > 1)
    {
        Console.WriteLine("error: you can use only one switch at a time (-l, -s, -d)");
        return null;
    }
    var selSwitch = switches.Count() == 0 ? "l" : switches.First().Substring(1);
    if (!"lsd".Contains(selSwitch))
    {
        Console.WriteLine("error: valid switches: -l(ist), -s(how contents), -d(elete)");
        return null;
    }
    return selSwitch;
}

ProcessFile will process one file. If the user passed a directory name, we enumerate all files in the directory and call ProcessFile for each file.

private static void ProcessFile(string fileName, string streamName, string selSwitch)
{
    switch (selSwitch)
    {
        case "l":
            ListStreams(fileName);
            break;
        case "s":
            ShowContents(fileName, streamName);
            break;
        case "d":
            DeleteStream(fileName, streamName);
            break;
    }
}

Then, we have three kind of processing: if the user wants to list the names, we call ListStreams:

private static void ListStreams(string fileName)
{
    FileInfo file = new FileInfo(fileName);
    Console.WriteLine($"{file.Name} - {file.Length:n0}");
    foreach (AlternateDataStreamInfo s in file.ListAlternateDataStreams())
        Console.WriteLine($"    {s.Name} - {s.Size:n0}");
}

It will enumerate all streams and list their names and sizes. The second processing is to show the contents, in ShowContents:

private static void ShowContents(string fileName, string streamName)
{
    FileInfo file = new FileInfo(fileName);
    Console.WriteLine($"{file.Name} - {file.Length:n0}");
    if (!string.IsNullOrWhiteSpace(streamName) &amp;&amp; file.AlternateDataStreamExists(streamName))
    {
        AlternateDataStreamInfo s = file.GetAlternateDataStream(streamName, FileMode.Open);
        ShowContentsOfStream(file, s);
    }
    else if (string.IsNullOrWhiteSpace(streamName))
        foreach (AlternateDataStreamInfo s in file.ListAlternateDataStreams())
            ShowContentsOfStream(file, s);
}

If the user passed a name of a valid stream, it will show its contents. If it has not passed a name, the program will enumerate all streams and show the contents for them all. The ShowContentsOfStream method is:

private static void ShowContentsOfStream(FileInfo file, AlternateDataStreamInfo s)
{
    Console.WriteLine($"    {s.Name}");
    using (TextReader reader = s.OpenText())
    {
        Console.WriteLine(reader.ReadToEnd());
    }
}

Finally, the third kind of processing is to delete the streams. For that, we use the DeleteStreams method:

private static void DeleteStream(string fileName, string streamName)
{
    FileInfo file = new FileInfo(fileName);
    Console.WriteLine($"{file.Name} - {file.Length:n0}");
    if (!string.IsNullOrWhiteSpace(streamName) && file.AlternateDataStreamExists(streamName))
    {
        file.DeleteAlternateDataStream(streamName);
        Console.WriteLine($"    {streamName} deleted");
    }
    else if (string.IsNullOrWhiteSpace(streamName))
        foreach (AlternateDataStreamInfo s in file.ListAlternateDataStreams())
        {
            s.Delete();
            Console.WriteLine($"    {s.Name} deleted");
        }
}

If the user passed a valid stream name, the program will delete that stream. If he hasn’t passed a name, the program will delete all streams in the file.

That way, we arrived at the end of our program.

Conclusions

ADSs are used in many ways, to add extra data to a file. Although there are legitimate ways to use them, sometimes, that can be used to store harmful data. We have developed a tool that can list all ADSs in a file, show their contents or delete them. With it, you can analyze the data that is attached to your file and decide what to do with it. Next time you get something that came from the internet and is blocked, you can easily unblock it with this tool.

The full source code is in http://github.com/bsonnino/ADSViewer

This last part in the series will show a different kind of sensor – the Geolocation sensor. In the strict sense, we can’t call this as a sensor, because the geolocation service will get the current location from the GPS sensor if it exists. If not, it will use other methods, like the network of wifi to detect the current location.

To get the current location, you must work in a different way that we worked for the other sensors:

  • You must add the Location capability to the app manifest
  • The user must consent with the use of the current location
  • You should instantiate a new Geolocator instance (and not get one with GetDefault)
  • There is no ReadingChanged event, but StatusChanged event

Even with these changes, you will see that it’s very easy to work with the geolocation. In this post we will develop a program that gets the current location and queries a weather service to get the forecast and see if it will rain.

Will it rain?

In Visual Studio, create a blank UWP project. To query the weather, we will use an open source project that has a C# API to query the OpenWeather map (http://openweathermap.org/API), located in https://github.com/joancaron/OpenWeatherMap-Api-Net. We can add this lib by using the Nuget Package manager (right click the References node in Solution Explorer and select Manage Nuget Packages). Just search for openweather and install the lib:

image

Just one note here: the official package doesn’t support Windows 10, so you must choose a fork of the project (the third project in the list) to install.

Then, you must add the Location capability to the app manifest. On the solution Explorer, open package.appxmanifest and go to the tab Capabilities. There, check the Location box.

image

Then, in the Main window, add this XAML:

[sourcecode language=”csharp” padlinenumbers=”true”]
<Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
<TextBlock x:Name="RainText"
HorizontalAlignment="Center"
VerticalAlignment="Center"
FontSize="30"/>
</Grid>
[/sourcecode]

In the constructor of MainPage, we must ask for the user permissions an process the response:

[sourcecode language=”csharp”]
public MainPage()
{
this.InitializeComponent();
InitializeLocator();
}

public enum RainStatus
{
Rain,
Sun
};

private async void InitializeLocator()
{
var userPermission = await Geolocator.RequestAccessAsync();
switch (userPermission)
{
case GeolocationAccessStatus.Allowed:
RainText.Text = "Updating rain status…";
Geolocator geolocator = new Geolocator();
Geoposition pos = await geolocator.GetGeopositionAsync();
try
{
RainText.Text = await GetRainStatus(pos) == RainStatus.Rain ?
"It’s possible to rain, you’d better take an umbrella" :
"It will be a bright an shiny day, go out and enjoy";
}
catch
{
RainText.Text = "Got an error while getting weather";
}
break;

case GeolocationAccessStatus.Denied:
RainText.Text = "I cannot check the weather if you don’t give me the access to your location…";
break;

case GeolocationAccessStatus.Unspecified:
RainText.Text = "I got an error while getting location permission. Please try again…";
break;
}
}
[/sourcecode]

If the user allows access to the location data, we get the current position with GetGeopositionAsync and then we use this position to get the rain status, using the open weather map API. The GetRainStatus method is:

[sourcecode language=”csharp”]
private async Task GetRainStatus(Geoposition pos)
{
var client = new OpenWeatherMapClient("YourPrivateId");
var weather = await client.CurrentWeather.GetByCoordinates(new Coordinates()
{
Latitude = pos.Coordinate.Point.Position.Latitude,
Longitude = pos.Coordinate.Point.Position.Longitude
});
return weather.Precipitation.Mode == "no" ? RainStatus.Sun : RainStatus.Rain;
}
[/sourcecode]

To use the OpenWeather API, you must register with the site and get an API key. For low usage, the key and usage is free. You can register at http://openweathermap.org/appid

When you run the program, you are able to know if you will need to take an umbrella to go out:

image

Conclusions

As you could see, working with sensors is very easy and it can offer a better experience for your users. You can integrate them with your apps in many different ways. In this post, I’ve shown how to use the weather API to query if it will rain in your location, a simple, but useful program.

All source code for this project is in https://github.com/bsonnino/GeoLocation

In the previous posts (Light sensor, Compass and Inclinometer), I’ve shown how to use some sensors in a UWP app. In this post, I’ll show how to use another sensor, the accelerometer. The accelerometer will measure the acceleration of the device. This measure is very useful to see when the device is moved.

This sensor will show the acceleration in the three axis, X, Y and Z, and has a particularity: as it will show the forces that the device is submitted, its measure usually is not 0, because the device is always submitted to the gravity force (unless you take it to the space). The normal measure for the standing device is 1, the gravity force. When you move it, the measure should be different than 1.

Making a ball jump in UWP

For this post, I will develop a program that shows a ball at the bottom of the window, and when the user shakes the device, the ball jumps, using an animation. The stronger the shake, the ball will jump higher.

The sensor gives three measures, but I am not interested in the acceleration in every axis. I just want the magnitude of the acceleration, and that’s given by this formula:

[sourcecode language=”text”]
magnitude = sqrt(x^2 + y^2 + z^2)
[/sourcecode]

The magnitude of the acceleration is the square root of the sum of the squares of the three measures.

With this information, we can start our program. Create a new blank UWP solution. In the main page, change the main element to a Canvas and add an ellipse to it:

[sourcecode language=”xml”]
<Canvas Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
<Ellipse Width="80" Height="80" Fill="Red" x:Name="Ball"/>
</Canvas>
[/sourcecode]

In the constructor of MainPage, add the code to position the ball, get the accelerometer and add the ReadingChanged event handler:

[sourcecode language=”csharp”]
public MainPage()
{
this.InitializeComponent();
Loaded += (s, e) =>
{
Canvas.SetLeft(Ball, ActualWidth / 2 – 40);
Canvas.SetTop(Ball, ActualHeight – 80);
var accelerometer = Accelerometer.GetDefault();
if (accelerometer == null)
{
return;
}
accelerometer.ReadingChanged += async (s1, e1) =>
{
await Dispatcher.RunAsync(Windows.UI.Core.CoreDispatcherPriority.Normal, () =>
{
var magnitude = Math.Sqrt(
e1.Reading.AccelerationX * e1.Reading.AccelerationX +
e1.Reading.AccelerationY * e1.Reading.AccelerationY +
e1.Reading.AccelerationZ * e1.Reading.AccelerationZ);
if (magnitude &gt; 1.5)
JumpBall(magnitude);

});
};
};
}
[/sourcecode]

The code is very similar to the ones in the previous posts: we set the ball position to the bottom of the window and then set the ReadingChanged event handler. This handler gets the magnitude of the reading and then, if the magnitude is greater than 1.5G, it calls JumpBall, to make the ball jump. The code for JumpBall is:

[sourcecode language=”csharp”]
private void JumpBall(double acceleration)
{
var da = new DoubleAnimation()
{
From = ActualHeight-80,
To = ActualHeight-80-acceleration * 200,
AutoReverse = true,
Duration = new Duration(TimeSpan.FromSeconds(1))
};
Storyboard.SetTarget(da, Ball);
Storyboard.SetTargetProperty(da, "(Canvas.Top)");
var sb = new Storyboard();
sb.Children.Add(da);
sb.Begin();
}
[/sourcecode]

We create a DoubleAnimation with the bottom of the window as the starting point, the end point is given by the magnitude of the reading. The animation is related to the Canvas.Top attached property, related to the ball. With all that set, we start the animation.

That way, when the user shakes the device, the ball jumps. Now, when you run the app and shake the device, the ball will jump.

image

Conclusions

With the accelerometer, you can give your users more interactivity, detecting when they move or shake the device and act accordingly. The accelerometer is very easy to use and can improve the games usability a lot.

The full source code for this project is in https://github.com/bsonnino/JumpingBall

In the previous two posts (Light sensor and Compass), I’ve shown how to use the sensors in a UWP app. Working with them is very easy and it can enhance the usability of your app. In this post, we willshow how to use another sensor, the Inclinometer.

This sensor is used a lot for games, as it detects the inclination of the device. That way, the user can control the game by tilting the device. Pretty cool, no? It’s note a pure sensor, as you won’t have an inclinometer in your device, but it gets its data from other two sensors, the accelerometer and the gyroscope.

The sensor usage is similar to the other sensors, and it shows three measures, Yaw (the rotation on the Z axis), Pitch (rotation on the X axis) and Roll (rotation on the Y axis):

inclinometer

(source – https://msdn.microsoft.com/en-us/windows/uwp/devices-sensors/sensors)

Playing with a ball in UWP

To show the usage f an inclinometer, we will create a project that can be a starting point for a game. We will draw a ball in the window and, depending on how the user tilts the device, the ball will move faster or slower, to the left and to the right.

We will start creating a new UWP blank app. Change the main element in the main page to a Canvas and add a new Ellipse to it:

[sourcecode language=”xml” padlinenumbers=”true”]
<Canvas Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
<Ellipse Width="80" Height="80" Fill="Red" x:Name="Ball"/>
</Canvas>
[/sourcecode]

In the constructor of the MainPage, we position the ball and add the code to initialize the inclinometer and set its ReadingChanged event handler:

[sourcecode language=”csharp”]
public MainPage()
{
this.InitializeComponent();
Loaded += (s, e) =>
{
Canvas.SetLeft(Ball, ActualWidth / 2 – 40);
Canvas.SetTop(Ball, ActualHeight – 80);
var inclinometer = Inclinometer.GetDefault();
if (inclinometer == null)
{
return;
}
inclinometer.ReadingChanged += async (s1, e1) =>
{
await Dispatcher.RunAsync(Windows.UI.Core.CoreDispatcherPriority.Normal, () =>
{
var position = Canvas.GetLeft(Ball);
var newPosition = position + e1.Reading.RollDegrees;
if (newPosition ActualWidth – 80)
newPosition = ActualWidth – 80;
Canvas.SetLeft(Ball, newPosition);
});
};
};
}
[/sourcecode]

As you can see, this time I’m doing all the initialization in the handler of the Loaded event of the page. That’s because ActualWidth and ActualHeight of the page aren’t set before the Loaded event fires, and if I don’t use this handler, the ball would be placed in the wrong place. As we have a Canvas, we position the ball with the attached properties Left and Top. In the code behind, this is done with the static methods Canvas.SetLeft and Canvas.SetTop.

The next step is to get the Inclinometer sensor with GetDefault and set its ReadingChanged handler. It will get the current position of the ball and will set the new position depending on the Roll (number of degrees of tilt in the Y position). That way, if the user tilts more, the ball will move faster. If he tilts less, it will move slower.

With that code in place, we have our moving ball project complete and can run it. If your device has an inclinometer, you can see the ball moving. If it doesn’t have, you can use a Windows Phone and see the same app running there.

image

Conclusions

Using the inclinometer is very simple and you can provide your users a different kind of input with it, you just need to get its reading and move the elements in your app according to the tilt of the device.

The source code for this app is in https://github.com/bsonnino/MovingBall

In the last post, I have shown how to use the light sensor to get light data and offer a better experience for the user. In this post, I will show another sensor available in 2-in-1 devices and tablets: the compass. The compass is a sensor the shows the direction, related to the magnetic north.

On physical compasses, this reading is given by a magnetic needle that is always pointing to the magnetic north. When you turn the compass, it will show you where are you heading to. In computers and smartphones, there is no magnetic needle, but the sensor shows the angle of the device, related to the magnetic north. To use the sensor, we must create a program that does the same three steps of the last post:

  • Get an instance of the sensor with the GetDefault method
  • Set its properties
  • Set a handler for the ReadingChanged

In this post, we will create a program that simulates a physical compass and shows the heading of the device.

Creating a compass simulator in UWP

The first step is to create a blank UWP project. In this project, add images tor the compass background and needle (I got my background from http://www.clipartbest.com/images-of-a-compass and the needle from http://www.clker.com/clipart-compassnorth.html) in the Assets folder.

Then, add the two images to the main window:

[sourcecode language=”xml” padlinenumbers=”true”]
<Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
    <Image Source="Assets\\Compass.png" HorizontalAlignment="Stretch"
           VerticalAlignment="Stretch" Stretch="Uniform"/>
    <Image Source="Assets\\Compassnorth-Hi.png" HorizontalAlignment="Stretch"
           VerticalAlignment="Stretch" Stretch="Uniform" x:Name="Needle"/>
</Grid>
[/sourcecode]

In the constructor of MainWindow, we must get the compass and set the ReadingChanged event handler:

[sourcecode language=”csharp”]
public MainPage()
{
this.InitializeComponent();
var compass = Compass.GetDefault();
if (compass == null)
{
return;
}
compass.ReadingChanged += async (s, e) =>
{
await Dispatcher.RunAsync(Windows.UI.Core.CoreDispatcherPriority.Normal, () =>
{
RotateNeedle(e.Reading.HeadingMagneticNorth);
});
};
}
[/sourcecode]

The event handler just calls RotateNeedle, passing the reading angle as parameter. RotateNeedle is very simple:

[sourcecode language=”csharp”]
private void RotateNeedle(double angle)
{
var transform = new RotateTransform() { Angle = angle };
Needle.RenderTransformOrigin = new Windows.Foundation.Point(0.5, 0.5);
Needle.RenderTransform = transform;
}
[/sourcecode]

It just creates a RotateTransform, setting the angle to the reading angle, sets the origin of the rotation on the middle of the needle and then sets the RenderTransform property to this transform.

With this, you have a compass simulator that works both on desktops and smartphones. As you turn the device, the needle will be pointing to the magnetic north and the head will show you the direction.

image

Conclusions

As you can see, working with the compass is very easy, you can easily get the reading of the sensor and change the view, depending on what the user is heading. This is one more tool that you can use to give the user a better experience.

The full source code for the project is in https://github.com/bsonnino/Compass

Some time ago, computer makers introduced new classes of Windows devices: the 2-in-1 and the tablets. These kinds of computers bring a lot of innovation – the 2-in-1 computers can be used as notebooks and tablets, while still maintaining their power: you can have very powerful devices, that can be used at the office and on the road, thus avoiding the need of having a tablet and a notebook.

But this kind of devices have another kind of innovations that are not visible at first sight: sensors. With them, you can have the same experience you have with a smartphone – you can use the accelerator for games or gestures, the GPS for location and routing and many others. This series of posts will show how to use these sensors in UWP, so you can give your user a better experience, so he can use all the resources of his device. And all this with an added bonus, thanks to UWP development – the same project will work both on desktop devices and smartphones.

Working with sensors in UWP

Basically, working with sensors in UWP is pretty much the same:

  • You get an instance of the sensor with the GetDefault method
  • You set its properties
  • You set a handler for the ReadingChanged

That’s all that is needed to work with sensors in UWP. So, let’s go and start with the first sensor: the light sensor.

Working with the light sensor

The light sensor can be used to detect the environment lighting and adjust the screen brightness according to the external light, so the use has the best experience. In this post I will show a simple way to create the effect used in GPS devices: when it’s day, it shows the display with a white background and when it’s night, it shows it with a black background.

To get this effect, the simplest way is to use themes. UWP has three default themes, Dark, Light and High Contrast and you can set them by using the RequestedTheme property of the control (in our case, the main window). So, let’s start.

In Visual Studio create a UWP application and add this XAML to the main page:

[sourcecode language=”xml” padlinenumbers=”true”]

<Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
<TextBlock Text="Day" HorizontalAlignment="Center" x:Name="MainText"
VerticalAlignment="Center" FontSize="48" />
</Grid>
[/sourcecode]

Then, in the MainPage constructor, we will initialize the light sensor and process its readings:

[sourcecode language=”csharp”]
public MainPage()
{
this.InitializeComponent();
var lightSensor = LightSensor.GetDefault();
if (lightSensor == null)
{
MainText.Text = "There is no light sensor in this device";
return;
}
lightSensor.ReportInterval = 15;
lightSensor.ReadingChanged += async (s, e) =>
{
await Dispatcher.RunAsync(Windows.UI.Core.CoreDispatcherPriority.Normal, () =>
{
if (e.Reading.IlluminanceInLux < 30)
{

RequestedTheme = ElementTheme.Dark;
MainText.Text = "Night";
}
else
{
RequestedTheme = ElementTheme.Light;
MainText.Text = "Day";
}
});
};
}
[/sourcecode]

We must use the Dispatcher to change the theme and text, because the ReadingChanged can be called in a different thread of the UI thread. When the Illuminance reading is less than 30 Lux, we change to the Dark theme and change the text to Night.

Now, when you run the program in a device that has a light sensor, you will see the default view in daylight like this:

Day

If you cover the light sensor to simulate the lack of light, you will see something like this:

Night

Conclusions

As you can see, it’s very easy to work with sensors. With them, you can give a better experience for your users, so they can enjoy using your apps. And a added benefit is that you can use the same app in a desktop or in a Windows Phone.

The source code for this app is in https://github.com/bsonnino/LightSensor

In the last post, I showed how to load a complete view dynamically, but that’s not the most common way to change the visualization of data. Most of the time, you will want to just change the appearance of the view, customizing the style for a client.

If we want to apply the styles for all controls, we must use a Theme. A Theme provides the default appearance for all controls of an application. The default theme is provided by the OS the app is running, but that can be changed by using an alternate theme file, a resource dictionary that has default styles for all controls.

Loading a theme dynamically

One way to load themes dynamically is to use any theme dll available for our use (many of them are free). We can add the themes to our project using Nuget and then change the theme as we want, but that’s not the focus, here. We want to load the themes from loose XAML files dynamically.

For that, I used an open source project, named WpfThemes (https://wpfthemes.codeplex.com/), that has several themes available and creates a themes dll that can be used in our project. As it is open source, I won’t use the dll, but I will use the theme structure and its demo to show how to load the theme from its files.

I downloaded the project and restructured it in this way:

  • I created a single project, LoadThemes, and added the content of the demo main window to the new project’s main window
  • I created a new folder on the project, named Themes and added all themes folders from the WPF.Themes project
  • I set all Theme.xaml file Build Action to None and Copy to output Directory to “ Copy if newer”

With this structure, we can load all available theme names to the theme combobox using this code:

[sourcecode language='csharp'  padlinenumbers='true']
private void LoadThemes()
{
    themes.ItemsSource = Directory.EnumerateDirectories("Themes").Select(t => t.Substring(7));
}
[/sourcecode]

I just enumerate all folders under the Themes folder and get the folder names, removing the initial “Themes\”. Now, we must load the theme dynamically. This is done in the SelectionChanged event for the theme combobox:

[sourcecode language='csharp'  padlinenumbers='true']
private void themes_SelectionChanged(object sender, System.Windows.Controls.SelectionChangedEventArgs e)
{
    if (e.AddedItems.Count == 0)
        return;
    using (FileStream fs = new FileStream($"Themes\\{e.AddedItems[0]}\\Theme.xaml", FileMode.Open))
    {
        var dict = XamlReader.Load(fs) as ResourceDictionary;
        if (dict != null)
        {
            Application.Current.Resources.Clear();
            Application.Current.Resources.MergedDictionaries.Add(dict);
        }
    }
}
[/sourcecode]

The program gets the selected item and opens the Theme.xaml located in the selected folder. Then, it loads the file as a ResourceDictionary and sets the MergedDictionaries for the current Application to it. This is everything that’s needed to change the style of all controls at once.

image

Loading styles dynamically

Usually, you do not want such a radical change, like the theme change, but you want to change the way some controls are drawn (colors, margins, etc). For that, you just need to change some styles. One way to do it is to apply some styles to your controls and then load the resource dictionaries dynamically. For example, the project from previous post could be redesigned by using styles. We can take the Master/Detail file and apply styles to the file, setting something like this:

[sourcecode language='xml' ]
<UserControl xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
             xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
             mc:Ignorable="d"
             d:DesignHeight="600" d:DesignWidth="800" Foreground="{StaticResource PageForeground}">
    <UserControl.Resources>
        <Style TargetType="TextBlock" >
            <Setter Property="Foreground" Value="{StaticResource PageForeground}" />
        </Style>
    </UserControl.Resources>
    <Grid Background="{StaticResource PageBackground}">
        <Grid.RowDefinitions>
            <RowDefinition Height="40" />
            <RowDefinition Height="*" />
            <RowDefinition Height="2*" />
            <RowDefinition Height="50" />
        </Grid.RowDefinitions>
        <StackPanel Orientation="Horizontal">
            <TextBlock Text="Country" VerticalAlignment="Center" Margin="5"/>
            <TextBox Height="25"
                     VerticalAlignment="Center" Margin="5,3" Width="250" Text="{Binding SearchText, Mode=TwoWay}"  />
            <Button Content="Search" Width="75" Height="25" Margin="10,5" VerticalAlignment="Center" 
                    Command="{Binding SearchCommand}" Style="{StaticResource ButtonStyle}"/>
        </StackPanel>
        <DataGrid AutoGenerateColumns="False" x:Name="master" CanUserAddRows="False" CanUserDeleteRows="True" Grid.Row="1"
                  ItemsSource="{Binding Customers}" SelectedItem="{Binding SelectedCustomer, Mode=TwoWay}" >
            <DataGrid.Columns>
                <DataGridTextColumn x:Name="customerIDColumn" Binding="{Binding Path=CustomerId}" Header="Customer ID" Width="80" />
                <DataGridTextColumn x:Name="companyNameColumn" Binding="{Binding Path=CompanyName,ValidatesOnDataErrors=True}" Header="Company Name" Width="300" />
                <DataGridTextColumn x:Name="cityColumn" Binding="{Binding Path=City}" Header="City" Width="100" />
                <DataGridTextColumn x:Name="countryColumn" Binding="{Binding Path=Country}" Header="Country" Width="100" />
            </DataGrid.Columns>
        </DataGrid>
        <Grid DataContext="{Binding SelectedCustomer}" Grid.Row="2">
            <Grid Name="grid1" >
                <Grid.ColumnDefinitions>
                    <ColumnDefinition Width="Auto" />
                    <ColumnDefinition Width="*" />
                </Grid.ColumnDefinitions>
                <Grid.RowDefinitions>
                    <RowDefinition Height="Auto" />
                    <RowDefinition Height="Auto" />
                    <RowDefinition Height="Auto" />
                    <RowDefinition Height="Auto" />
                    <RowDefinition Height="Auto" />
                    <RowDefinition Height="Auto" />
                    <RowDefinition Height="Auto" />
                    <RowDefinition Height="Auto" />
                    <RowDefinition Height="Auto" />
                    <RowDefinition Height="Auto" />
                    <RowDefinition Height="Auto" />
                </Grid.RowDefinitions>
                <TextBlock Text="Customer Id:" Grid.Column="0" Grid.Row="0"  Margin="3" VerticalAlignment="Center" />
                <TextBox Grid.Column="1" Grid.Row="0"   Margin="3" Name="customerIdTextBox" Text="{Binding Path=CustomerId, Mode=TwoWay, ValidatesOnExceptions=true, NotifyOnValidationError=true}" VerticalAlignment="Center"  />
                <TextBlock Text="Company Name:" Grid.Column="0" Grid.Row="1"  Margin="3" VerticalAlignment="Center" />
                <TextBox Grid.Column="1" Grid.Row="1"   Margin="3" Name="companyNameTextBox" Text="{Binding Path=CompanyName, Mode=TwoWay, ValidatesOnExceptions=true, NotifyOnValidationError=true}" VerticalAlignment="Center"  />
                <TextBlock Text="Contact Name:" Grid.Column="0" Grid.Row="2"  Margin="3" VerticalAlignment="Center" />
                <TextBox Grid.Column="1" Grid.Row="2"   Margin="3" Name="contactNameTextBox" Text="{Binding Path=ContactName, Mode=TwoWay, ValidatesOnExceptions=true, NotifyOnValidationError=true}" VerticalAlignment="Center"  />
                <TextBlock Text="Contact Title:" Grid.Column="0" Grid.Row="3"  Margin="3" VerticalAlignment="Center" />
                <TextBox Grid.Column="1" Grid.Row="3"   Margin="3" Name="contactTitleTextBox" Text="{Binding Path=ContactTitle, Mode=TwoWay, ValidatesOnExceptions=true, NotifyOnValidationError=true}" VerticalAlignment="Center"  />
                <TextBlock Text="Address:" Grid.Column="0" Grid.Row="4" HorizontalAlignment="Left" Margin="3" VerticalAlignment="Center" />
                <TextBox Grid.Column="1" Grid.Row="4" Margin="3" Name="addressTextBox" Text="{Binding Path=Address, Mode=TwoWay, ValidatesOnExceptions=true, NotifyOnValidationError=true}" VerticalAlignment="Center" />
                <TextBlock Text="City:" Grid.Column="0" Grid.Row="5"  Margin="3" VerticalAlignment="Center" />
                <TextBox Grid.Column="1" Grid.Row="5"   Margin="3" Name="cityTextBox" Text="{Binding Path=City, Mode=TwoWay, ValidatesOnExceptions=true, NotifyOnValidationError=true}" VerticalAlignment="Center"  />
                <TextBlock Text="Postal Code:" Grid.Column="0" Grid.Row="6"  Margin="3" VerticalAlignment="Center" />
                <TextBox Grid.Column="1" Grid.Row="6"   Margin="3" Name="postalCodeTextBox" Text="{Binding Path=PostalCode, Mode=TwoWay, ValidatesOnExceptions=true, NotifyOnValidationError=true}" VerticalAlignment="Center"  />
                <TextBlock Text="Region:" Grid.Column="0" Grid.Row="7"  Margin="3" VerticalAlignment="Center" />
                <TextBox Grid.Column="1" Grid.Row="7"   Margin="3" Name="regionTextBox" Text="{Binding Path=Region, Mode=TwoWay, ValidatesOnExceptions=true, NotifyOnValidationError=true}" VerticalAlignment="Center"  />
                <TextBlock Text="Country:" Grid.Column="0" Grid.Row="8"  Margin="3" VerticalAlignment="Center" />
                <TextBox Grid.Column="1" Grid.Row="8"   Margin="3" Name="countryTextBox" Text="{Binding Path=Country, Mode=TwoWay, ValidatesOnExceptions=true, NotifyOnValidationError=true}" VerticalAlignment="Center"  />
                <TextBlock Text="Phone:" Grid.Column="0" Grid.Row="9"  Margin="3" VerticalAlignment="Center" />
                <TextBox Grid.Column="1" Grid.Row="9"   Margin="3" Name="phoneTextBox" Text="{Binding Path=Phone, Mode=TwoWay, ValidatesOnExceptions=true, NotifyOnValidationError=true}" VerticalAlignment="Center"  />
                <TextBlock Text="Fax:" Grid.Column="0" Grid.Row="10"  Margin="3" VerticalAlignment="Center" />
                <TextBox Grid.Column="1" Grid.Row="10"   Margin="3" Name="faxTextBox" Text="{Binding Path=Fax, Mode=TwoWay, ValidatesOnExceptions=true, NotifyOnValidationError=true}" VerticalAlignment="Center"  />
            </Grid>
        </Grid>
        <StackPanel Orientation="Horizontal" HorizontalAlignment="Right" Margin="5" Grid.Row="3">
            <Button Width="75" Height="25" Margin="5" Content="Add" Command="{Binding AddCommand}" Style="{StaticResource ButtonStyle}"/>
            <Button Width="75" Height="25" Margin="5" Content="Remove" Command="{Binding RemoveCommand}" Style="{StaticResource ButtonStyle}"/>
            <Button Width="75" Height="25" Margin="5" Content="Save" Command="{Binding SaveCommand}" Style="{StaticResource ButtonStyle}"/>
        </StackPanel>
    </Grid>
</UserControl>
[/sourcecode]

We can create a default resource dictionary and call it DefaultDict.xaml:

[sourcecode language='xml' ]
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
                    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
                    xmlns:local="clr-namespace:CustomerApp">
    <SolidColorBrush x:Key="PageForeground" Color="Black" />
    <SolidColorBrush x:Key="PageBackground" Color="AliceBlue" />
    <Style x:Key="ButtonStyle" TargetType="Button">
        <Setter Property="Background" Value="BlanchedAlmond" />
        <Setter Property="Margin" Value="10,0" />
    </Style>
</ResourceDictionary>
[/sourcecode]

And add this dictionary to App.xaml:

[sourcecode language='xml' ]
<Application.Resources>
    <ResourceDictionary>
        <ResourceDictionary.MergedDictionaries>
            <ResourceDictionary Source="DefaultDict.xaml" />
        </ResourceDictionary.MergedDictionaries>
    </ResourceDictionary>
</Application.Resources>
[/sourcecode]

When we run the application, the default style is applied to the view:

image

Now, we want to apply dynamic styles to the view, so we can create loose files with new resource dictionaries. In the project, create a new folder and name it Styles. In this folders, add three files and name them as Blue.xaml, Red.xaml and Yellow.xaml:

[sourcecode language='xml' ]
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
                    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
                    xmlns:local="clr-namespace:CustomerApp">
    <SolidColorBrush x:Key="PageForeground" Color="White" />
    <SolidColorBrush x:Key="PageBackground" Color="Navy" />
    <Style x:Key="ButtonStyle" TargetType="Button">
        <Setter Property="Background" Value="Azure" />
        <Setter Property="Margin" Value="10,0" />
    </Style>
    <Style TargetType="TextBlock" >
        <Setter Property="FontFamily" Value="Arial" />
    </Style>
</ResourceDictionary>
[/sourcecode]
[sourcecode language='xml' ]
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
                    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
                    xmlns:local="clr-namespace:CustomerApp">
    <SolidColorBrush x:Key="PageForeground" Color="White" />
    <SolidColorBrush x:Key="PageBackground" Color="Red" />
    <Style x:Key="ButtonStyle" TargetType="Button">
        <Setter Property="Background" Value="LightPink" />
        <Setter Property="Margin" Value="10,0" />
    </Style>
    <Style TargetType="TextBlock" >
        <Setter Property="FontFamily" Value="Times New Roman" />
    </Style>
</ResourceDictionary>
[/sourcecode]
[sourcecode language='xml' ]
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
                    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
                    xmlns:local="clr-namespace:CustomerApp">
    <SolidColorBrush x:Key="PageForeground" Color="Black" />
    <SolidColorBrush x:Key="PageBackground" Color="Yellow" />
    <Style x:Key="ButtonStyle" TargetType="Button">
        <Setter Property="Background" Value="BlanchedAlmond" />
        <Setter Property="Margin" Value="10,0" />
    </Style>
    <Style TargetType="TextBlock" >
        <Setter Property="FontFamily" Value="Comic Sans MS" />
    </Style>
</ResourceDictionary>
[/sourcecode]

And set their Build Action to None and Copy to output directory to “Copy if newer”. As you can see, these files are very similar to the default dictionary: they override some colors and styles and add a new one, setting the font for all TextBlocks.

Then, add a new Combobox in the main window, to select the new styles:

[sourcecode language='xml' ]
<ComboBox x:Name="StylesCombo" Height="30" Width="200" 
            SelectionChanged="SelectedStyleChanged" HorizontalAlignment="Right" Margin="5" />
[/sourcecode]

The SelectionChanged event handler for this box is:

[sourcecode language='csharp' ]
private void SelectedStyleChanged(object sender, SelectionChangedEventArgs e)
{
    if (e.AddedItems.Count == 0)
            return;
        using (FileStream fs = new FileStream($"Styles\\{e.AddedItems[0]}", FileMode.Open))
        {
            var dict = XamlReader.Load(fs) as ResourceDictionary;
            if (dict != null)
            {
                Application.Current.Resources.MergedDictionaries.Add(dict);
            }
        }
}
[/sourcecode]

When you run the program and try to change the styles, you will see a strange thing:

image

The font that was not defined in the default style is changed, but the colors have not changed. This happens because we have set the styles as Static, using StaticResource when we applied the styles. In order for the style be applied dynamically, we must apply it using DynamicResource. When we change all StaticResource to DynamicResource in the master/detail file, we get this:

image

All the colors and styles have changed.

Conclusions

As you can see, WPF gives you a great flexibility to change you views dynamically. You can change the entire view, restyle all controls or only change the style of part of the controls. Everything can be done at runtime, and you can load the files from anywhere you want: loose files in a selected folder, from a database or from a request to a server, you can load the XAML as a string, parse and load it into your program.

The files for this project are in https://github.com/bsonnino/LoadThemes (runtime themes) and https://github.com/bsonnino/DynamicXamlViews (dynamic styles).