Monthly Archives: March 2017

CSS Overlaying Controls (absolute and relative positioning)

Having looked at CSS in the past, and thought that it’s probably something that people who are better at UI design that me should concern themselves with, I’ve recently been playing with it while looking at the new Dot Net Core web apps.

The problem that I’m looking at in this particular article is how to overlay one control on top of another. I have no doubt that there are dozens of possibilities; but the two specific ones that I’ll be focusing on are positioning absolute and relative.

Target

The idea here is for a web-page that looks like this:

Target Layout

HTML

The HTML is pretty basic for this:

<body>
  <form>
    <div>
      <img src=""  />
    </div>
    <div class="overlay">
      <input type="text" name="destination" />
    </div>
  </form>
</body>

CSS: absolute positioning

We have the basic elements, so now it’s down to CSS to make the screen above. By default, web browsers will render the div’s sequentially, and so the input box will appear below the image.

One possibility is to use “absolute” positioning. This means that I can position an element without regard to where other elements on the page might be; here’s an example:

.overlay {
    position: absolute; 
    top: 30%;         
    text-align: center;
    z-index: 10;
}

img {
  background-color: blue;
  width: 100%;
  height: 500px;
}

I’ve used 30% here because it matters on the size of your viewport – so that’s not ideal. Also, the centre align doesn’t work. This kind of makes sense when you think about it, because you’re using an absolute position – so what do you want to centralise it to?

CSS: relative positioning

Relative positioning took me a while to work out. It sounds like it’s relative to something else – but it’s actually relative to itself. Here’s what I tried for relative positioning:

.overlay {
    position: relative;
    width: 80%;
    height: 35px;
    top: -50px;
    border: none;
    text-align: center;
    z-index: 10;    
}

As you can see, it’s top position is negative, so it moves up from where it would have been. Also, because the positioning is relative, the centre align now works, because it’s back in the flow of the page.

References

https://css-tricks.com/absolute-relative-fixed-positioining-how-do-they-differ/

https://www.w3.org/Style/Examples/007/center.en.html#block

Find user’s current location and display on Bing maps (v6.3)

Using Bing Maps to display the user’s current position should be an easy task. As with everything in Javascript, this kind of thing is only easy if you know the magic text.

HTML

<body onload="LoadMap();">
    <div class="row">
        <div>
            <h2>Where do you want to go?</h2>
        </div>
    </div>

    <div class="row">        
        <div id="pnlMap" style="position:relative">
        </div>
    </div>

There are a few points here: first one is that you need a name for the pnlMap (referenced later is the javascript), and style=”position:relative” prevents the map from just displaying in a random location.

Javascript

var map;

function LoadMap() {        
    map = new VEMap('pnlMap');    
    navigator.geolocation.getCurrentPosition(findMe);
}

function findMe(position) {
          
    var latlong = new VELatLong(position.coords.latitude,
        position.coords.longitude);
    map.LoadMap(latlong, 10);
}

LoadMap() sets up the map variable and associates it to the relevant HTML control, and then getCurrentPosition calls back to findMe(). The second number on LoadMap is the zoom level; 1 shows me as living on the earth, and 20 goes right into the road that I live on.

The output is a map that centres on your current location:

Slightly offset to avoid hordes of angry JS programmers beating down my door and suggesting that dynamically typed languages are as good as statically typed ones!

V6.3

As you will see from the references below, the latest version is v8. If you use v8, then you have to register for a key… but I didn’t want to… and I still got a map. I suppose I’ve done a bad thing.

References

https://www.w3schools.com/html/html5_geolocation.asp

https://msdn.microsoft.com/en-us/library/bb259692.aspx

https://msdn.microsoft.com/en-us/library/cc161074.aspx

https://social.technet.microsoft.com/wiki/contents/articles/34568.bing-maps-v6-3-to-v8-migration-guide.aspx

http://stackoverflow.com/questions/42607156/using-bing-maps-with-bootstrap

Testing for Exceptions using the Arrange Act Assert Pattern in C# 7

Unit testing massively benefits from following the Arrange / Act / Assert pattern. I’ve seen tests that are not written in this way, and they can be sprawling and indecipherable, either testing many different things in series, or testing nothing at all except the .Net Framework.

I recently found an issue while trying to test for an exception being thrown, which is that Nunit (and probably other frameworks) test for an exception by accepting a delegate to test. Here’s an example:

        [Test]
        public void Test_ThrowException_ExceptionThrown()
        {
            // Arrange
            TestClass tc = new TestClass();

            // Act / Assert
            Assert.Throws(typeof(Exception), tc.ThrowException);
        }

We’re just testing a dummy class:

    public class TestClass
    {
        public void ThrowException()
        {
            throw new Exception("MyException");
        }
    }

C# 7 – Inline functions

If you look in the references at the bottom, you’ll see something more akin to this approach:

        public void Test_ThrowException_ExceptionThrown2()
        {
            // Arrange
            TestClass tc = new TestClass();

            // Act
            TestDelegate throwException = () => tc.ThrowException();            

            // Assert
            Assert.Throws(typeof(Exception), throwException);
        }

However, since C# 7, the option on a local function has arrived. The following has the same effect:

        [Test]
        public void Test_ThrowException_ExceptionThrown3()
        {
            // Arrange
            TestClass tc = new TestClass();

            // Act
            void CallThrowException()
            {
                tc.ThrowException();
            }

            // Assert
            Assert.Throws(typeof(Exception), CallThrowException);
        }

I think that I, personally, still prefer the anonymous function for this; however, the local function does present some options; for example:


        [Test]
        public void Test_ThrowException_ExceptionThrown4()
        {
            void CallThrowException()
            {
                // Arrange
                TestClass tc = new TestClass();

                // Act
                tc.ThrowException();
            }

            // Assert
            Assert.Throws(typeof(Exception), CallThrowException);
        }

Now I’m not so sure that I still prefer the anonymous function.

References

http://stackoverflow.com/questions/33897323/nunit-3-0-and-assert-throws

https://pmbanugo.wordpress.com/2014/06/16/exception-testing-pattern/

http://stackoverflow.com/questions/24070115/best-approach-towards-applying-the-arrange-act-assert-pattern-when-expecting-exc

WPF Performance – TextBlock

WPF typically doesn’t have many performance issues and, where it does, this can usually be fixed by virtualisation. Having said that, even if you never need to use this, it’s useful to know that you can eek that last ounce of performance out of the system.

Here’s a basic program that contains a TextBlock:

<Window x:Class="TextBlockTest.MainWindow"
        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"
        xmlns:local="clr-namespace:TextBlockTest"
        mc:Ignorable="d"
        Title="MainWindow" Height="350" Width="525"
        x:Name="MainWindowView">
    <Grid>
        <ScrollViewer>
            <ItemsControl ItemsSource="{Binding BigList, ElementName=MainWindowView}" Margin="0,-1,0,1">
                <ItemsControl.ItemTemplate>
                    <DataTemplate>
                        <TextBlock Text="{Binding}"/>
                    </DataTemplate>
                </ItemsControl.ItemTemplate>
            </ItemsControl>
        </ScrollViewer>
    </Grid>
</Window>

Code behind:

using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;

namespace TextBlockTest
{
    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window
    {
        public ObservableCollection<string> BigList { get; set; }

        public MainWindow()
        {
            BigList = new ObservableCollection<string>();
            for (int i = 0; i <= 10000; i++)
            {
                BigList.Add($"Item {i}");
            }

            InitializeComponent();
        }
    }
}

Let’s, for a minute, imagine this is slow, and profile it:

The layout is taking most of the time. Remember that each control needs to be created, and remember that the TextBlock does slightly more than just display text:

The whole panel took 3.46s. Not terrible, performance, but can it be improved? The answer is: yes, it can! Very, very slightly.

Let’s create a Custom Control:

using System;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;

namespace FastTextBlock
{
   
    public class MyTextBlockTest : Control
    {
        private FormattedText _formattedText;

        static MyTextBlockTest()
        {
            //DefaultStyleKeyProperty.OverrideMetadata(typeof(MyTextBlockTest), new FrameworkPropertyMetadata(typeof(MyTextBlockTest)));
        }

        public static readonly DependencyProperty TextProperty =
             DependencyProperty.Register(
                 "Text", 
                 typeof(string),
                 typeof(MyTextBlockTest), 
                 new FrameworkPropertyMetadata(string.Empty, FrameworkPropertyMetadataOptions.AffectsMeasure,
                    (o, e) => ((MyTextBlockTest)o).TextPropertyChanged((string)e.NewValue)));

        private void TextPropertyChanged(string text)
        {
            var typeface = new Typeface(
                new FontFamily("Times New Roman"),
                FontStyles.Normal, FontWeights.Normal, FontStretches.Normal);

            _formattedText = new FormattedText(
                text, CultureInfo.CurrentCulture,
                FlowDirection.LeftToRight, typeface, 15, Brushes.Black);
        }


        public string Text
        {
            get { return (string)GetValue(TextProperty); }
            set { SetValue(TextProperty, value); }
        }

        protected override void OnRender(DrawingContext drawingContext)
        {
            if (_formattedText != null)
            {
                drawingContext.DrawText(_formattedText, new Point());
            }
        }

        protected override Size MeasureOverride(Size constraint)
        {
            //return base.MeasureOverride(constraint);

            return _formattedText != null
            ? new Size(_formattedText.Width, _formattedText.Height)
            : new Size();
        }
    }
}

Here’s the new XAML:

    <Grid>
        <ScrollViewer>
            <ItemsControl ItemsSource="{Binding BigList, ElementName=MainWindowView}" Margin="0,-1,0,1">
                <ItemsControl.ItemTemplate>
                    <DataTemplate>
                        <!--<TextBlock Text="{Binding}"/>-->
                        <controls:MyTextBlockTest Text="{Binding}" />
                    </DataTemplate>
                </ItemsControl.ItemTemplate>
            </ItemsControl>
        </ScrollViewer>
    </Grid>

Shaves around 10ms off the time:

Even more time can be shaved by moving up an element (that is, inheriting from a more base class than `Control`. In fact, `Control` inherits from `FrameworkElement`:

public class MyTextBlockTest : FrameworkElement

Shaves another 10ms off:

Conclusion

Clearly, this isn’t a huge performance boost, and in 99% of use cases, this would be massively premature optimisation. However, the time that this really comes into its own is where you have a compound control (a control that consists of other controls), and you have lots of them (hundreds). See my next post for details.

References:

https://social.msdn.microsoft.com/Forums/en-US/94ddd25e-7093-4986-b8c8-b647924251f6/manual-rendering-of-a-wpf-user-control?forum=wpf

http://www.codemag.com/article/100023

http://stackoverflow.com/questions/20338044/how-do-i-make-a-custom-uielement-derived-class-that-contains-and-displays-othe

http://stackoverflow.com/questions/42494455/wpf-custom-control-inside-itemscontrol

sdk\1.0.0-rc4-004771 Disappeared Creating a .Net Core project in VS2015

Error MSB4019 The imported project “C:\Program Files\dotnet\sdk\1.0.0-rc4-004771\Microsoft\VisualStudio\v14.0\DotNet\Microsoft.DotNet.Props” was not found. Confirm that the path in the declaration is correct, and that the file exists on disk. MyProject C:\Users\Paul\documents\visual studio 14\Projects\MyProject\Myproject\MyProject.xproj

This issue, on initial investigation, looks like a problem with the VS Tools location (defined here in the xproj):

  <Import Project="$(VSToolsPath)\DotNet\Microsoft.DotNet.Props" Condition="'$(VSToolsPath)' != ''" />

However, the fix was in the new file Global.json:

{
  "projects": [ "src", "test" ],
  "sdk": {
    "version": "1.0.0-preview2-003131"
  }
}

When the project was migrated to VS2017, the global.json was changed to look like this:

{"projects":["src","test"]}

So it looks like MS are moving away from the idea of these external project / solution state definition files. Which is a shame, because I really thought they were a good idea.

References

https://www.microsoft.com/net/download/core

https://jeremylindsayni.wordpress.com/2016/11/20/upgrading-from-net-core-1-0-t0-1-1-with-visual-studio-2015/

Using Entity Framework Core with DBFirst

Say what you like about ORM frameworks, but they do decrease time to market. My impression, as someone that has generally had very little exposure to them, is that, whilst they can make it very quick to get something up and running, they make it very easy to shoot yourself in the foot.

With all the hype about .Net Core, I thought I’d give EF Core a go, and this post is a document of my initial set-up which was, by no means, a straight forward process!

The General Idea of an ORM

The purpose of an ORM is to abstract data access, in a manner similar to the following:

The great advantage of this is that you can very quickly make database changes and maintain a layer of abstraction between the DB and the accessing layer. Obviously, the downside is that you don’t have the same level of control over this access.

Pre-requisites

The first step is to install the SDK from here. Like everything else in this post, this web-site is not as straight-forward as it appears. Make sure that you select “Current” and “SDK”:

I used x64. That matters when you get further down.

Database First

In this particular installation, I’m using the “Database First” model. What that means is that I already have a database, and it is sat on an accessible machine. The following project will create classes to access that. For details of how to create a database using a VS project, see this article that I wrote on unit testing databases.

Project set-up

The first step is to create your project.

What is the difference between ASP.NET Core (.NET Core) and ASP.NET Core (.NET Framework)?

In this instance, we’ll go with .Net Core. The difference between the two is that one of them (.NET Framework) references the .NET Framework, and so will not be cross platform. Obviously, picking .NET Core is your smallest footprint, and least functionality.

Pick Web API here, as we’re essentially just writing a service that accesses a DB (see the diagram above).

The next step is to install Entity Framework Core:

https://www.nuget.org/packages/Microsoft.EntityFrameworkCore/

A note on project.json

This is a new file that has been introduced into the .Net Core world, and it is (IMHO) a huge improvement on the flakey confusion of NuGet package management. The idea is that you declare your dependencies, in a similar way that you might declare your variables in a program. When you change this, or when you ask it to, VS will simply go and get these packages for you. This means, for example, that I can paste my project.json in this post, and you, the reader (or future me), can simply paste this directly into yours and VS will do the rest… so:

{
  "dependencies": {
    "Microsoft.ApplicationInsights.AspNetCore": "2.0.0",
    "Microsoft.AspNetCore.Hosting.Abstractions": "1.1.0",
    "Microsoft.AspNetCore.Mvc": "1.1.1",
    "Microsoft.AspNetCore.Routing": "1.1.0",
    "Microsoft.AspNetCore.Server.IISIntegration": "1.1.0",
    "Microsoft.AspNetCore.Server.Kestrel": "1.1.0",
    "Microsoft.EntityFrameworkCore": "1.1.0",
    "Microsoft.EntityFrameworkCore.Design": "1.1.0",
    "Microsoft.EntityFrameworkCore.Relational.Design": "1.1.0",
    "Microsoft.EntityFrameworkCore.SqlServer": "1.1.0",
    "Microsoft.EntityFrameworkCore.Tools.DotNet": "1.1.0-preview4-final",
    "Microsoft.Extensions.Configuration.Json": "1.1.0",
    "Microsoft.Extensions.Logging": "1.1.0",
    "Microsoft.Extensions.Logging.Console": "1.1.0",
    "Microsoft.Extensions.Logging.Debug": "1.1.0",
    "Microsoft.Extensions.Options.ConfigurationExtensions": "1.1.0",
    "Microsoft.NETCore.App": {
      "version": "1.1.0",
      "type": "platform"
    },
    "NETStandard.Library": "1.6.1",
    "System.Collections.NonGeneric": "4.3.0",
 
    "Microsoft.EntityFrameworkCore.SqlServer.Design": {
      "version": "1.1.0",
      "type": "build"
    },
    "Microsoft.EntityFrameworkCore.Tools": {
      "version": "1.1.0-preview4-final",
      "type": "build"
    }
  },
 
  "tools": {
    "Microsoft.AspNetCore.Server.IISIntegration.Tools": "1.0.0-preview2-final",
    "Microsoft.EntityFrameworkCore.Tools": "1.1.0-preview4-final"
  },
 
  "frameworks": {
    "netcoreapp1.1": {
      "imports": [
        "dotnet5.6",
        "portable-net45+win8"
      ]
    }
  },
 
  "buildOptions": {
    "emitEntryPoint": true,
    "preserveCompilationContext": true
  },
 
  "runtimeOptions": {
    "configProperties": {
      "System.GC.Server": true
    }
  },
 
  "runtimes": {
    "win10-x64": {}
  },
 
  "publishOptions": {
    "include": [
      "wwwroot",
      "**/*.cshtml",
      "appsettings.json",
      "web.config"
    ]
  },
 
  "scripts": {
    "postpublish": [ "dotnet publish-iis --publish-folder %publish:OutputPath% --framework %publish:FullTargetFramework%" ]
  }
}

If you now simply open a package manager window in VS and type:

dotnet restore

VS should do the rest.

The next thing that you’ll need to update is the appsettings.json:

{
 
  "ConnectionStrings": {
    "JourneyDB": "Data Source=ServerName\\DatabaseInstance; Initial Catalog=MyDatabase; Integrated Security=SSPI"
  },
  
  "Logging": {
    "IncludeScopes": false,
    "LogLevel": {
      "Default": "Debug",
      "System": "Information",
      "Microsoft": "Information"
    }
  }
}

Scaffolding

So, you should now have a project that’s ready to go. I suggestion, unless you’re reading this in around a year from now (2018) when all this has been stabilised, is that you restart VS. In fact, this should be your first response if anything in this post doesn’t do what you expect (it is still in preview, so I’m not judging).

The next step is to call the following command:

Scaffold-DbContext "Server=ServerName\DatabaseInstance;Database=MyDatabase;Trusted_Connection=True;" Microsoft.EntityFrameworkCore.SqlServer -OutputDir Models

What should that do (because it doesn’t)?

Okay, it took me a good while to get this to actually work, so the chance of it working first time is pretty remote; but when it does work, you should get a mirror of your DB in the project:

Using it

As you can see, I have a `JourneyHeader`; here’s the code to get the contents of that table:

namespace JourneyService.Controllers
{
    [Route("api/[controller]")]
    public class JourneyController : Controller
    {
        // GET api/values
        [HttpGet]
        public IEnumerable<JourneyHeader> Get()
        {
            using (JourneyDatabaseContext context = new JourneyDatabaseContext())
            {
                return context.JourneyHeader.ToList();
            }            
        }

And here’s the proof that it works:

References

https://code.msdn.microsoft.com/How-to-using-Entity-1464feea

http://www.dotnetspeak.com/asp-net-core/write-your-first-api-with-asp-net-core-and-entity-framework-core/

https://docs.microsoft.com/en-us/ef/core/get-started/aspnetcore/existing-db

http://michaelcrump.net/getting-started-with-aspnetcore/

https://github.com/dotnet/core/blob/master/release-notes/rc4-download.md

https://blogs.msdn.microsoft.com/dotnet/2016/11/16/announcing-entity-framework-core-1-1/

http://stackoverflow.com/questions/42393977/setting-up-database-first-ef-project-using-scaffold-dbcontext

http://stackoverflow.com/questions/42393977/setting-up-database-first-ef-project-using-scaffold-dbcontext?noredirect=1#comment71956574_42393977