Friday, 26 August 2016

CSS switching in Asp.Net

Websites are legally obligated in the UK to provide accessible versions of the site for the benefit of users with visual disabilities. This is often achieved by switching the site styling on demand, such that the full-colour graphics-heavy design is replaced by one or more text-based high contrast versions.

This in turn is usually achieved by switching the site CSS according to user selection; and in the wild the switching can often be driven by a complex set of scripting commands cobbled together from chunks found on Stack Overflow, some local customisation, and a liberal application of the old maxim that if the javascript isn’t working, add a bit more javascript.

However faced with implementing this wobbly heap recently, I found that actually the same thing can be achieved with pure with very few lines of code. As per usual error trapping and so forth has been removed for ease of showing the central concept.


A web site. Old-school fully-templated aspx, master/child, MVC, it doesn’t matter. There are two CSS files defined, standard.css which is the full graphic experience, and hiviz.css which renders the site as black text on a yellow background. The site developers have been very extremely well behaved and have put all of their stylings into the css. The following example calls two methods in a Tools class, GetCookie and SetCookie, which do exactly what you’d expect.

Public Shared Sub SetCookie(ByVal CookieName As String, ByVal CookieValue As String)
    With HttpContext.Current.Response
        .Cookies(CookieName).Expires = Now.AddMonths(6)
        .Cookies(CookieName).Value = CookieValue
    End With

End Sub

Public Shared Function GetCookie(ByVal CookieName As String) As String

   Dim strValue As String = ""
   For i As Integer = 0 To HttpContext.Current.Request.Cookies.Count - 1
       If HttpContext.Current.Request.Cookies.Item(i).Name = CookieName Then
            strValue = HttpContext.Current.Request.Cookies.Item(i).Value
            Exit For
       End If
       Return strValue
   End Function

Step 1: page header 

The key to this is in the declaration of the css in the page header.

<head runat="server">

    <link id="lkStandardSwitch" href="CSS/standard.css" rel="stylesheet" /></head>

The css declaration is given an id so that it is addressable in code, and the default set as standard.css. That default behaviour is also set in code, but declaring it here keeps the Visual Studio IDE happy.

Step 2: Master page Page_Load event 

In the master page’s Page Load event (or an embedded ascx if you prefer) …

Dim lk As HtmlLink = CType(Page.FindControl("lkStandardSwitch"), HtmlLink)
Dim strCookie As String = Tools.GetCookie("WhichCss")
strCookie = If(strCookie = "", "standard", strCookie)
lk.Attributes("href") = "CSS/" & strCookie & ".css"

If the user has selected one of the accessible css options, that is retrieved from a cookie and the HtmlLink is amended to use that css; otherwise the standard.css is used.

Step 3: CSS selection by the user

To capture the user requirement to display an accessible css, simply write the name of the selected css into the cookie from a button press …

Tools.SetCookie("WhichCss", “hiviz”)

And to update the current page to the new css


And you’re done. Apply to all pages and relax.

In real life of course you may need to switch several CSSs, but this is easily extensible; just remember to use a separate cookie for each css, and then only call the Response.Redirect once when all the updates have been applied. Your visually impaired users will thank you, your accessibility QA team will thank you, and a future you or you-replacement will thank you when they don't have to unpick 40 lines of spaghetti javascript.

Saturday, 20 August 2016

Date of last backup

From my previous posts, you're running BgInfo, and you're doing regular on-demand backups to OneDrive.

So let's add a line to BgInfo, showing you when you last did a backup to OneDrive.

  1. Add a line to your backup script to write the date out to a text file. You could actually write anything to the file, because it's the file date we shall be using in BgInfo, but the date is as good as anything.

    @echo %DATE% > c:\folder\PhysicalLastDate.txt
  2. Create a new User Defined Field in BgInfo; use the Timestamp of a file, and point that at the file you've just written in step 1.
  3. Add the new field to BgInfo and save your settings.
And that's it!

Tuesday, 22 March 2016

Backup to OneDrive

OneDrive, out of the box, is very focussed on making your files available across all your devices; but what if you just want to use it as a cloud backup?

A little bit of scripting will come to your rescue. I'm sure the same could be done with PowerShell, but I'm an old die-hard .bat user when the opportunity arises!

Create a new batch file, and set up robocopy to copy all the files you want to back up to the OneDrive directory located under your user directory (e.g. C:\Users\Fred\OneDrive). Even if you want to back up your entire data volume you will want to exclude directories like System Volume Information and the Recycle Bin because they can cause sharing violations; so use the robocopy /xd syntax. I also found that the /fft switch prevented files being missed due to slight timestamp differences.

Once you're done, save that file out with a .bat extension, and you're good to go.

I've created a menu shortcut and run the backup manually a few times a week. The file copies everything to the local OneDrive directory and then it's down to how quick your upload speed is.

Now you just need to configure OneDrive itself. Open the Settings dialogue. On the Settings tab, make sure 'Start OneDrive automatically when I sign into Windows' is ticked and 'let me use OneDrive to fetch any of my files on this PC' is unticked.' One the Account tab click Choose Foilders, and make sure that the selected directories are as near as possible to the structure you're actually going to back up (although as the batch file will be doing the pushing it's not too essential).

Click OK to exit the OneDrive settings, and you're good to go with your online cloud backup of up to 15Gb. (You did claim your full 15Gb didn't you).

Friday, 15 January 2016

BGInfo again - full versioning

I was trying to get BgInfo to display the same version information for Windows 10 as that shown in winver, that is at the time of writing Version 1511 (OS Build 10586.63).

Which I didn't quite achieve ...

To create that I added two new registry keys to BgInfo:

HKEY_LOCAL_MACHINE\SOFTWARE\WOW6432Node\Microsoft\Windows NT\CurrentVersion\ReleaseId

which I called OS Release ID, and

HKEY_LOCAL_MACHINE\SOFTWARE\WOW6432Node\Microsoft\Windows NT\CurrentVersion\BuildLabEx

which I named OS Detail.

I added those to BgInfo as 

OS Detail              <OS Release ID> <OS Build Version> 

Then refreshed the desktop as in my previous post.

Tuesday, 15 December 2015

BgInfo on Windows 10

After the recent Windows 10 update to version 1511, the bgInfo wallpaper wasn’t refreshing, which meant that fields such as the snapshot date rapidly became illegible:

The solution is to open BgInfo, and load your .bgi file.

Click on the Background button.

Mine was set to Copy user’s wallpaper settings, which I assume is the default. 

Change that to ‘Use these settings’ and set your preferred background up.

Click OK on this dialogue, then Apply on the main BgInfo screen; all will be well again.

Thursday, 10 December 2015

Automatically hyperlinked numbers on iPads

The Safari browser on the iPad has added a ‘feature’ where numbers are automatically hyperlinked, so that the number can be phoned just by clicking on the link.

All well and good, until you display a number that isn't a telephone number, such as a serial number or a customer identifier.

To stop this irritating behaviour put the following tag in your master page or page header:

    <meta name="format-detection" content="telephone=no">