In December 2015, SharpDX 3.0.0 was released, followed by 3.0.1 in January 2016. This new version features several major changes, as well as some new features. For example, the assemblies are now more light weight by for example moving mathematics to a separate assembly. SharpDX now also supports Direct3D12 (requires Windows 10).

What’s removed and when shouldn't I upgrade?

But while Direct3D12 is now present, Direct3D10 has been removed, along with the toolkit. SharpDX 3.0.0 also requires .NET 4.5, so if you can’t use that, you will have to stay on 2.6.3. Some pretty nice helper functions, such as Texture.FromFile(...), which allowed easy loading of textures from files are also no longer supported (I will cover how to load textures in a later tutorial).

So, as we are geeks who always wants the latest and greatest we will from now on use SharpDX 3.0.1. Below are the steps on how to upgrade the Part 4 tutorial project to SharpDX 3.0.1:

  1. Open the solution in Visual Studio.
  2. Go to “Tools” -> “NuGet Package Manager” -> “Package Manager Console” to open the NuGet console.

     
  3. Enter the following command:
    Update-Package SharpDX.Direct3D11 -Version 3.0.1
    You should get an ouput similar to this:

    This will also update SharpDX and SharpDX.DXGI to 3.0.1, because SharpDX.Direct3D11 depends on those.
     
  4. Now we also have to update SharpDX.D3DCompiler, using the following command:
    Update-Package SharpDX.D3DCompiler -Version 3.0.1
     
  5. We will now be at version 3.0.1, but if you try to build you will get several compiler errors:

    This is because all math has moved into a separate assembly, SharpDX.Mathematics, and RenderForm has moved into the SharpDX.Desktop assembly, so we have to install those as well. So run the following two commands in the NuGet console:
    Install-Package SharpDX.Mathematics -Version 3.0.1
    Install-Package SharpDX.Desktop -Version 3.0.1

     
  6. Build the project again, it should now compile and run correctly, but now with SharpDX 3.0.1.

NuGet says there are no updates are available?

This happened for me as well first, if NuGet gives the error message:

No updates available for ‘SharpDX.Direct3D11’ in project ‘MySharpDXGame’.

Then you will probably have to clear the NuGet cache. Use the following steps:

  1. Go to “Tools” -> “Options…”
  2. Open “NuGet Package Manager” tab
  3. Click “Clear Package Cache”

     
  4. Re-run the commands in the console, it should now update correctly.

This concludes tutorial 4.5. All the tutorial sources on GitHub have now already been updated to SharpDX 3.0.1, so if you download the code there you won’t have to do those steps yourself.

Now that we have a window with Direct3D initialized it is finally time to draw something, and just as all other tutorials out there, we will also start with drawing a triangle! To render our first triangle there are actually quite many parts we must add, so let’s get started.

1. Vertices

To create the triangle, we will use vertices. A vertex is an exact point in a 3D space, which can also hold additional information (which we will see in later tutorials). For now, our vertices will only be represented by 3 values, its x, y, and z-coordinates.

For the triangle we will need 3 vertices, one for each corner. We will cover more details about the different coordinate system later, but for now our visible space is between -1 and 1 in x‑, y‑, and z‑directions. This is how I decided to set up the triangle, you can play around with the different values to see how triangle changes:

So the first code we add is a variable to our Game class which holds those coordinates, for this we use the Vector3 class provided in SharpDX:

private Vector3[] vertices = new Vector3[] { new Vector3(-0.5f, 0.5f, 0.0f), new Vector3(0.5f, 0.5f, 0.0f), new Vector3(0.0f, -0.5f, 0.0f) };

2. Vertex Buffers

The vertices array we just created is stored in the system memory, but for rendering our objects we will need to transfer the data to the video memory. For this we will use Buffers. In DirectX we have three different types of buffers, Vertex, Index, and Constant buffers. The data in buffers are automatically copied from system memory to video memory when we our rendering needs the data by DirectX.

The vertex buffer is what we will use now, this buffer type, as the name implies, holds data for each vertex. For now, our vertices only have a position vector, but later on we will add more information to each vertex. First step here is to add a new variable to our class which is a reference to our buffer:

private D3D11.Buffer triangleVertexBuffer;

Then we add a new method to our class called InitializeTriangle, like this:

private void InitializeTriangle()
{
   triangleVertexBuffer = D3D11.Buffer.Create<Vector3>(d3dDevice, D3D11.BindFlags.VertexBuffer, vertices);
}

Here the method D3D.Buffer.Create<T> is used to create a new buffer, the generic type parameter T specifies of which data type of each element in the buffer. The first argument is the Direct3D device we wish to use. The second argument is which type of buffer we want to create, in this case a vertex buffer. Lastly we provide the initial data to load into the buffer, in this case our array of positions.
Also add a call to this method at the end of the Game class constructor, and dispose the buffer:

public Game()
{
   [...]
   InitializeTriangle();
} 

public void Dispose()
{
   triangleVertexBuffer.Dispose();
   [...]
}

3. Vertex and Pixel shaders

The graphics pipeline in DirectX 11 consists of several programmable steps. Now we will focus on the Vertex Shader Stage and Pixel Shader Stage.

The vertex shader stage is responsible for processing vertices, this can include for example transformations (translating, rotating, scaling, etc).

The pixel shader stage processes runs for each pixel, and received interpolated per-vertex data, as well as constant variables and textures. This shader is run for each pixel of the rendered primitive, and should return the final color of the pixel.

First we add two class variables, our vertex and pixel shader:

private D3D11.VertexShader vertexShader;
private D3D11.PixelShader pixelShader;

Next we need to compile our shader code (which we will write soon), which we place in a new private method, a using directive at the top is also required:

using SharpDX.D3DCompiler;
[...]
private void InitializeShaders()
{
   using(var vertexShaderByteCode = ShaderBytecode.CompileFromFile("vertexShader.hlsl", "main", "vs_4_0", ShaderFlags.Debug))
   {
      vertexShader = new D3D11.VertexShader(d3dDevice, vertexShaderByteCode);
   }
   using(var pixelShaderByteCode = ShaderBytecode.CompileFromFile("pixelShader.hlsl", "main", "ps_4_0", ShaderFlags.Debug))
   {
      pixelShader = new D3D11.PixelShader(d3dDevice, pixelShaderByteCode);
   }
}

Here we first point at which files to compile, vertexShader.hlsl and pixelShader.hlsl. We also specify the name of the entry point method in the shader code, “main”. Then we also set which version of HLSL to use, in this case 4.0. Finally, we also set the compilation to debug mode.

The device context must now also be configured to use those shaders when drawing, so add this code to the end of the InitializeShaders() method:

private void InitializeShaders()
{
    [...]
    // Set as current vertex and pixel shaders
    d3dDeviceContext.VertexShader.Set(vertexShader);
    d3dDeviceContext.PixelShader.Set(pixelShader);

    d3dDeviceContext.InputAssembler.PrimitiveTopology = PrimitiveTopology.TriangleList; 
}

Here we also set the primitive topology, this specifies how the vertices should be drawn. In this case we will use “Triangle List”, we will use other types in later tutorials, but you can check out the MSDN documentation for a good illustration of the different types.

Now, let’s add the shader code:

  1. Right click on the project in the solution explorer and select Add -> New Item…
  2. Find “Text File” and enter “vertexShader.hlsl” as name. Press Add.
  3. Select the file in the solution explorer, and in the Properties window, set “Copy to Output Directory” to “Copy Always”.
  4. Repeat step 1-3, but name the file “pixelShader.hlsl”.

Now open vertexShader.hlsl and write:

float4 main(float4 position : POSITION) : SV_POSITION
{
   return position;
}

Here we create our entry point method “main”, as we specified earlier. To start with the method only returns the same position that it gets from the vertex buffer. Notice the “: POSITION” and “: SV_POSITION”, this is called a semantic and specifies the intended use of the variable, we will see more of why this is important later in this tutorial.

Now open the pixelShader.hlsl file and enter the following code:

float4 main(float4 position : SV_POSITION) : SV_TARGET
{
   return float4(1.0, 0.0, 0.0, 1.0);
}

Again we create a main method, the parameter to the method is the output from the vertex shader. But remember that the vertex shader is run for each vertex, while pixel shader runs for each pixel, so this will be an interpolated position. From this method we return a float4, which is our color in the format red, green, blue, alpha. So this will produce a red color for all pixels. Worth noting is that the values in the float4 is between 0 and 1, so float4(0, 0, 0, 1) would give black, while float4(1, 1, 1, 1) would give a white pixel.

And of course also call our InitializeShaders() method in our game constructor and dispose of the shaders, this should go before the InitializeTriangle() method:

public Game()
{
   [...]
   InitializeDeviceResources();
   InitializeShaders();
   InitializeTriangle();
}
public void Dispose()
{
   triangleVertexBuffer.Dispose();
   vertexShader.Dispose();
   pixelShader.Dispose();
   [...]
}

4. Input layout

We now have a vertex buffer which has our vertex data. But DirectX also wants to know about how the data is structured and of what type each vertex element has, for this we use an Input Layout. This requires two step. First we need to describe each element in a vertex, and then create an input layout from that.

As our vertices only have one element so far, the position, so let’s add a new array of InputElements in our Game class:

private D3D11.InputElement[] inputElements = new D3D11.InputElement[] 
{
    new D3D11.InputElement("POSITION", 0, Format.R32G32B32_Float, 0)
};

The “POSITION” can be recognized from the shader code, this is called a semantic and is used to match with the input signature in the shader. The second parameter is which semantic slot to use, this is used if you have multiple POSITION semantics for example. Thirdly is the data type of this element, in this case 3 floats as the position for our vertices is Vector3.

Next we need to get the input shader from the compiled vertex shader. First create a new variable to hold the input signature to our Game class:

private ShaderSignature inputSignature;

Then in the InitializeShaders() method we can get the signature from the compiled shader byte code, like this:

using(var vertexShaderByteCode = ShaderBytecode.CompileFromFile("vertexShader.hlsl", "main", "vs_4_0", ShaderFlags.Debug))
{
    inputSignature = ShaderSignature.GetInputSignature(vertexShaderByteCode);
    [...]
}

Now we need to create an input layout from the array of InputElement and the input signature, so add another variable to the Game class:

private D3D11.InputLayout inputLayout;

And then assign it at the end of the InitializeShaders() method by creating a new InputLayout instance. Then we set this as the current input layout on the device context.

private void InitializeShaders()
{
    [...]
    inputLayout = new D3D11.InputLayout(d3dDevice, inputSignature, inputElements);
    d3dDeviceContext.InputAssembler.InputLayout = inputLayout;
}

The first element is our Direct3D device, and then our input signature from the shader and lastly the input elements array.

And don't forget to dispose the input layout and input signature:

public void Dispose()
{
    inputLayout.Dispose();
    inputSignature.Dispose();
    [...]
}

5. Set the viewport:

Before we draw anything we have to specify the viewport. DirectX uses something called Normalized Device Coordinates, specified as (-1, -1) in upper left corner, and (1, 1) in lower right corner (and therefore (0, 0) in the middle) of the screen. The viewport maps those corners to pixel coordinates.

Firstly create another variable in our Game class for the Viewport:

private Viewport viewport;

In the InitializeDeviceResources() method, create a new viewport and set it on the device context using the following code:

// Set viewport
viewport = new Viewport(0, 0, Width, Height);
d3dDeviceContext.Rasterizer.SetViewport(viewport);

The first two parameters are the x and y position of (-1, -1) and the last two parameters are how the width and height of the viewport. As we want to use the full window we map it tell it to start in the upper left corner (0, 0) and set it to the full width and height of the window.

6. Drawing the vertex data

After all this work, it is finally time to draw the triangle on the screen! This is just two method calls, which we add in the middle of our draw() method:

private void Draw()
{
    d3dDeviceContext.ClearRenderTargetView(renderTargetView, new SharpDX.Color(32, 103, 178));
    
    d3dDeviceContext.InputAssembler.SetVertexBuffers(0, new D3D11.VertexBufferBinding(triangleVertexBuffer, Utilities.SizeOf<Vector3>(), 0));
    d3dDeviceContext.Draw(vertices.Count(), 0);
    
    swapChain.Present(1, PresentFlags.None);
}

The first method tells the device context to use the vertex buffer holding the triangle vertex data, with the second parameter specifying the size (in bytes) for the data of each vertex. To get this size we use a nice helper method available in SharpDX.

The Draw() method on the device context draws vertices.Count() many vertices from our vertex buffer. The second parameter specifies the offset in our vertex buffer, by settings this to 1 for example, the first vertex would be skipped.

Now when you run the program you should get the following result:

 

As usual the code is available on GitHub: https://github.com/mrjfalk/SharpDXTutorials/tree/master/BeginnersTutorial-Part4

 

In this part we are going to initialize DirectX.

The first step we are going to do is add a new method called InitializeDeviceResources() to our Game class, like this:

private void InitializeDeviceResources()
{
}

First we will need to create a description for our back buffer, this is done with the following code:

using SharpDX.DXGI;
[...]
ModeDescription backBufferDesc = new ModeDescription(Width, Height, new Rational(60, 1), Format.R8G8B8A8_UNorm);
  • The first 2 parameters are the size of the back buffer, which in most cases should match the client width/height of the window we are rendering in.

  • The third parameter is the refresh rate in Hz (hertz), we set this to 60/1 = 60 Hz.

  • The last parameter is the format of the back buffer, here we specify a format with a red, green, blue, and alpha channel using 32-bit unsigned integer.

For a complete list see the MSDN documentation for DXGI_MODE_DESC.

The next step is to create a descriptor for our swap chain using the following code:

SwapChainDescription swapChainDesc = new SwapChainDescription()
{
    ModeDescription = backBufferDesc,
    SampleDescription = new SampleDescription(1, 0),
    Usage = Usage.RenderTargetOutput,
    BufferCount = 1,
    OutputHandle = renderForm.Handle,
    IsWindowed = true
};
  • ModeDescription: Here we provide our back buffer description.

  • SampleDescription: This is a descriptor for multisampling, we just specify one level (no multisampling) See DXGI_SAMPLE_DESC on MSDN.

  • Usage: Specify if/how the CPU can access the back buffer, as we are rendering to it we specify it as RenderTargetOutput. For other options see MSDN for DXGI_USAGE.

  • OutputHandle: Handle to the window to render in.

  • BufferCount: Number of buffers, we just need 1.

  • IsWindowed: Wheather we want to be in fullscreen or windowed mode.

Those are all we need to set right now, for the rest of the options, see DXGI_SWAP_CHAIN_DESC on MSDN.

Now that we have created our descriptions it is time to create the actual device and swap chain. First we declare three private class variables in our Game class:

using D3D11 = SharpDX.Direct3D11;
[...]
private D3D11.Device d3dDevice;
private D3D11.DeviceContext d3dDeviceContext;
private SwapChain swapChain;

We also added using D3D11 = SharpDX.Direct3D11;. We use this notation to avoid name conflicts between classes, and avoid having to write the full name, e.g. SharpDX.Direct3D11.Device.

Time to actually create our device and swap chain:

using SharpDX.Direct3D;
[...]
D3D11.Device.CreateWithSwapChain(DriverType.Hardware, D3D11.DeviceCreationFlags.None, swapChainDesc, out d3dDevice, out swapChain);
d3dDeviceContext = d3dDevice.ImmediateContext;
  • The first parameter specifies that we want to use the GPU.

  • We choose to not use any special flags, for possible flags see D3D11_CREATE_DEVICE_FLAG on MSDN.

  • Third parameter is our swap chain descriptor.

  • The last parameters are in which variables we want to store our swap chain and device in.

We also get our device context from the device.

Next we will create a back buffer which we can render to. First add another private class variable to hold our render target view:

private D3D11.RenderTargetView renderTargetView;

We get can get this from the swap chain by specifying which type of back buffer we want, in our case a Texture2D. Then we create a render target view from it and set it as the active render target view for the device context:

using (D3D11.Texture2D backBuffer = swapChain.GetBackBuffer<D3D11.Texture2D>(0))
{
    renderTargetView = new D3D11.RenderTargetView(d3d11Device, backBuffer);
}

d3d11DeviceContext.OutputMerger.SetRenderTargets(renderTargetView);

So, now we can finally render something, so why not use all of our graphic power and draw a blue screen! Let’s add a new method called Draw() to our Game class and add the following code:

private void Draw()
{
    d3dDeviceContext.ClearRenderTargetView(renderTargetView, new SharpDX.Color(32, 103, 178));
    swapChain.Present(1, PresentFlags.None);
}

This code first clears the render target view (currently our back buffer) and then swaps the back with the front buffer, making the back buffer visible. By specifying 1 as the first parameter to Present(…) we wait for vertical sync of the monitor before we present. This will limit the FPS to the update frequency of the monitor.

Now we are almost done, we need to first call InitializeDeviceResources() from our Game class constructor:

public Game()
{
    [...]

    InitializeDeviceResources();
}

Then we also need to call Draw() in our RenderCallback() method:

private void RenderCallback()
{
    Draw();
}

Finally we will add some clean-up to our Dispose() method:

public void Dispose()
{
    renderTargetView.Dispose();
    swapChain.Dispose();
    d3dDevice.Dispose();
    d3dDeviceContext.Dispose();
    renderForm.Dispose();
}

If you run this, you should now have a nice blue window, like this:

In the next tutorial we will look at rendering our first (of many) triangle. The full source can be found on my GitHub repo: https://github.com/mrjfalk/SharpDXTutorials

In this second tutorial we will look at creating a simple window which we later will render to.

  1. Firstly we will create a new class called Game. Right click the project and select “Add -> Class…”, name the file “Game.cs”.
    Create Game class.

  2. First we make the class public and then add a RenderForm along with two variables to hold the width and height of the window client size (the rendering size, does not include borders of the window). The RenderForm class also requires is to add a references to SharpDX.Windows.

    using SharpDX.Windows;
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Threading.Tasks;
    
    namespace MySharpDXGame
    {
       public class Game
       {
          private RenderForm renderForm;
    
          private const int Width = 1280;
          private const int Height = 720;
       }
    }

    The RenderForm is a subclass to a Windows.Form provided by SharpDX. This class, just like Windows.Form, provides us with a window that has borders, title bar etc. But it also provides us with a render loop which is optimized for 3D graphics. If you want to know more about this, take a look at the SlimDX (another wrapper similar to SharpDX) documentation: http://slimdx.org/tutorials/BasicWindow.php.

  3. Next we will add our constructor to the Game class which creates the RenderForm. We also need to add a reference to System.Drawing. We will also set a title and disable the user from resizing the window.

    using System.Drawing;
    
    [...]
    
    public Game()
    {
       renderForm = new RenderForm("My first SharpDX game");
       renderForm.ClientSize = new Size(Width, Height);
       renderForm.AllowUserResizing = false;
    }

     

  4. Next step is to add two methods to our Game class, one to start the rendering/game loop and another one which will be a callback method called each frame. This is done with the following code:

    public void Run()
    {
       RenderLoop.Run(renderForm, RenderCallback);
    }
    
    private void RenderCallback()
    {
    
    }


    We pass in our RenderForm and method to be called each frame to the RenderLoop.Run(…) method.

  5. We will now add a bit of clean up to our Game class, to make sure objects are disposed correctly. So we make our Game class implement the interface IDisposable:

    public class Game : IDisposable
    {
       [...]
       
       public void Dispose()
       {
          renderForm.Dispose();
       }
    }


    Here we also make sure to dispose our RenderForm.

  6. As a last step we will now run our game from the main method. So open the class “Program.cs”, which was automatically added when creating the “Console application project”, and change the Main(…) method to the following:

    [STAThread]
    static void Main(string[] args)
    {
       using(Game game = new Game())
       {
          game.Run();
       }
    }


    Because Game implements IDisposable it will automatically be disposed correctly due to the using statement. Read more about how this works here: https://msdn.microsoft.com/en-us/library/yh598w02.aspx.

  7. Now if you run the program you should see an empty window with the correct size and title bar text:
    SharpDX window

That was all for this tutorial, in the next part we will look at initializing the Direct3D device and set up a swap chain.

This is my first tutorial for using SharpDX. SharpDX allows you to render graphics using DirectX and C#. I recently started using SharpDX but there is not too much documentation and tutorials out there compared to other options, therefor I will be writing those tutorial as I go along.

Note: For those familiar with SharpDX you might know that it exists a toolkit to get a quick setup to get started, which gives a Game class similar to what is found in XNA. In those tutorials I will not be using the Toolkit.

In this tutorial we will not write any code, simply set up a new project in Visual Studio and add the required references.

  1. The first step is to create a new Console Application and give it a name:
    Create new project

  2. Next we need to add the references to SharpDX, for which we will use NuGet. Right click on “References” in the Solution Explorer and choose “Manage NuGet Packages…”

  3. Search for “SharpDX”. For now we will install those named “SharpDX”, “SharpDX.Direct3D11”, “SharpDX.DXGI”, and “SharpDX.D3DCompiler”. Now if you choose “Installed Packages” it should look like this:
    NuGet packages
    As you can see, there are many SharpDX packages available on NuGet, those we added are required to render a simple scene and compile our shaders.

We now have a correct project set up, in the next tutorial we will look at creating a simple window.

After getting the hero image in place for the hub control (see part 1), the next step is to get a nice status bar to go along with it. This is also present as a red bar in the MSN News app for example. This status bar is then present throughout the app.

Because the status bar is present throughout the application I will in this example add the code to the App.xaml.cs file. Firstly add a new function in App.xaml.cs:

public static async void SetStatusBar(string text = "Lizard App")
{
#if WINDOWS_PHONE_APP
   var statusBar = StatusBar.GetForCurrentView();
   statusBar.BackgroundColor = (App.Current.Resources["PhoneAccentBrush"] as SolidColorBrush).Color;
   statusBar.ForegroundColor = Colors.White;
   statusBar.BackgroundOpacity = 1;

   statusBar.ProgressIndicator.Text = text;
   statusBar.ProgressIndicator.ProgressValue = null;

   await statusBar.ProgressIndicator.ShowAsync();
#endif
}

As seen the function gets the status bar, sets the wanted color (users accent color as background and white as text color). As the status bar is not present in Windows 8 apps I make sure that the function only runs the code on Windows Phone. Now we just need to call the function, I do this from the function OnLaunched in App.xaml.cs, near line 100, see code snippet below:

         // When the navigation stack isn't restored navigate to the first page,
         // configuring the new page by passing required information as a navigation
         // parameter
         if (!rootFrame.Navigate(typeof(MainPage), e.Arguments))
         {
            throw new Exception("Failed to create initial page");
         }
         
         SetStatusBar();
      }

   // Ensure the current window is active
   Window.Current.Activate();
}

If you have a brand color you could use that as background color instead of using the users accent color. Here is an image of the result:

Status bar colored in Windows Store app.

When designing an app I wanted an appearance similar to the Bing MSN News app, as seen below:

So in a few blog posts I will describe how I recreated a similair look in my own apps. In this first part we will look at adding the background image of the first hub section. I am starting out on a new blank Windows Phone 8.1 Runtime app.

So the first step is to add a page with a Hub control, with the sections I want. Like the MSN News app, I am not setting the Header of the Hub control, as the status bar will be used for that instead:

<Hub>
    <HubSection>
    </HubSection>
    
    <HubSection Header="section two">
    </HubSection>
    
    <HubSection Header="section three">
    </HubSection>
    
    <HubSection Header="section four">
    </HubSection>
</Hub>

As you can see I also omit the Header on the first section. The next step is to add the image we want as hero image for the first section, so we set the background of the HubSection to the wanted image:

<HubSection>
    <HubSection.Background>
        <ImageBrush ImageSource="Assets/HeroImage.jpg" Opacity="0.75" Stretch="UniformToFill" />
    </HubSection.Background>
</HubSection>

But as seen in the screenshot below, the HubSection has an unwanted left margin:

To resolve this we have to edit the style of the HubSection, so add the following style on the page to remove the margin:

<Page.Resources>
    <ResourceDictionary>
        <Style x:Key="HubSectionHeroImage" TargetType="HubSection">
            <Setter Property="HorizontalContentAlignment" Value="Stretch"/>
            <Setter Property="VerticalContentAlignment" Value="Stretch"/>
            <Setter Property="Template">
                <Setter.Value>
                    <ControlTemplate TargetType="HubSection">
                        <Grid Background="{TemplateBinding Background}">
                            <Grid.RenderTransform>
                                <CompositeTransform x:Name="WrappingTransform"/>
                            </Grid.RenderTransform>
                            <ContentPresenter x:Name="ContentPresenter" ContentTemplate="{TemplateBinding ContentTemplate}" HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" Margin="{TemplateBinding Margin}" VerticalAlignment="{TemplateBinding VerticalContentAlignment}"/>
                        </Grid>
                    </ControlTemplate>
                </Setter.Value>
            </Setter>
        </Style>
    </ResourceDictionary>
</Page.Resources>

This style sets the Margin of the ContentPresenter to the template bound value, and not a fixed left margin (which was the default). Finally set the style to the first hub section:

<HubSection Style="{StaticResource HubSectionHeroImage}">

This gives a hero image which is nicely aligned to the left of the screen:

What is left to do now is adding content on top of the hero image, set application title in the status bar, and style the headers of the other hub sections.

In Windows/Windows Phone 8.1 store apps the class HttpUtility is not available to help parse query strings. So instead I decided to write a custom extension method to the Uri class which can parse the query string as a Dictionary<string,string>. My final extension function looks like this:

/// <summary>
/// Parse a query string into a System.Collections.Generic.Dictionary
/// </summary>
/// <param name="uri">Uri to parse query string from</param>
public static Dictionary<string, string> ParseQueryString(this Uri uri)
{
   WwwFormUrlDecoder decoder = new WwwFormUrlDecoder(uri.Query);
   return decoder.ToDictionary(x => x.Name, x => x.Value);
}

With example usage:

var parsedQueryString = new Uri("http://www.johanfalk.eu/search?query=windows%20phone&order=desc").ParseQueryString();
string query = parsedQueryString.ContainsKey("query") ? parsedQueryString["query"] : String.Empty; // Query is "windows phone"
string order = parsedQueryString.ContainsKey("order") ? parsedQueryString["order"] : String.Empty; // Order is "desc"

 

So, the first version of my new blog is finally ready for use. Here I will blog primarily about C# development for Windows, ASP.NET etc. Previously I've very infrequently blogged about this on http://attowares.com/blog, which will now be dedicated to app news.

This blog is written from scratch using ASP.NET MVC 5 and Entity Framework mostly as it is much more fun to create the blog from scratch.

So stay tuned for some upcoming posts and more content on this site!