Tuesday, 9 December 2014

Old new things for ADNUG

For the longest time, updates for the Adelaide .NET User Group (ADNUG) were sent out by email. Then around 3 years ago the transition was made to use LinkedIn Groups. There’s currently over 200 members there.

Earlier this year, I created a Twitter account for the group. Follow @AdlDNUG

A lot of user groups are also moving to Meetup to help coordinate their events. A few weeks ago ADNUG signed up, so you can now join https://www.meetup.com/Adelaide-dotNET/ and register to attend our events there.

More recently I was wondering what happened to the old email list. Hopefully most made the switch to LinkedIn – but maybe some didn’t bother, so I figured it might be worth firing up the list again just to see if it would help get the word out a bit further. Using MailChimp, I now have the email list running again. I plan to send out an email about once a month with meeting news and other relevant info. If you’d like to subscribe, click here.

Finally, after catching up with the ADNUG organising team today, I decided we should also be on Facebook. So if you like ADNUG, you can now share that fact with your friends!

By the way, our next meeting is this Wednesday 10th December, 6pm at Marcellina Adelaide. David Rogers will be presenting on the MembershipReboot library and claims authentication. Register now!

Looking ahead, as I mentioned in the email that went out a couple of days ago, I’m hoping to get some US-based Microsoft speakers to do virtual presentations next year. Just because we’re in Adelaide shouldn’t mean we can’t get access to great speakers where ever they might be – home grown, interstate, or even overseas.

So now there's lots of ways and lots of reasons to keep up with what's happing with .NET in Adelaide!

Thursday, 20 November 2014

Testing for Exceptions with NUnit

I’ve been aware for a long time usual way of writing a unit test with NUnit that expects an Exception to be thrown is to use the ExpectedExceptionAttribute on the test method.

[ExpectedException(typeof(ArgumentException)]
[Test]
public void Test()
{
    var sut = new ThrowUp();

    sut.DodgyMethod(3);
}

I hadn’t noticed that around the release of NUnit 2.5, an alternative was added. The Assert.Throws method allows you to be specific about which bit of code in the test should be throwing an exception.

public void Test()
{
    var sut = new ThrowUp();

    Assert.Throws<ArgumentException>( () => sut.DodgyMethod(3) );
}

I think it’s a good improvement, and makes it a bit clearer where the exception should be coming from.

Tuesday, 11 November 2014

ADNUG November–Azure for Developers

With the recent announcement that Azure now has two data centres located in Australia, I thought it was appropriate for the Adelaide .NET User Group (ADNUG) to spend some time looking at what’s involved in hosting your applications in the ‘cloud’.

The session will review what features Azure offers, and then we’ll step through hosting a simple web application and then scaling it up and out.

Register at http://www.acs.org.au/branches/south-australia/events/upcoming-events/event-details?eveID=10310633303016

Wednesday 12th November 2014 at 6.00 pm at Marcellina Adelaide (273 Hindley Street, Adelaide)

6.00 Pizzas and Networking
6.20 What’s New (Ryan Spears)
6.40 A Developer's guide to Microsoft Azure (David Gardiner)

Look forward to seeing you there!

Saturday, 25 October 2014

In the garden–Spring 2014

Not a lot of veggies planted at the moment. It has been an unusually warm spring so far. This week we had one day that got up to at least 36°C. That's more common for January than October.

Globe artichoke
A globe artichoke that Narelle planted last year has shot up again.

Lemonade fruit
The lemonade tree has been been very productive again. There's still a few fruit left. We've made quite a lot of juice this year.

Cabbages
These cabbages are growing well, though the cabbage moths (well actually their caterpillars) are doing their best to get in first.

Tiny lime fruit
We planted a lime tree a couple of years ago. It doesn't like our cold winters, but now the weather has warmed up it has put on a fresh lot of leaves. I'm hoping this tiny fruit will stay on the tree and grow to full size!

The roses are having their first bloom after winter. They are looking very colourful.

Roses in bloomPink standard rosePing roseIceberge rosesPink rosesYellow rosesDSC_4040DSC_4038DSC_4039

 

Lavendar flower with beeBearded iris flower
Lots of lavender and bearded iris are also flowering. The bees really like the lavender.

Plenty of weeding to do at this time of year too – but I'm not going to take photos of those!

Sunday, 12 October 2014

A healthy start

This week was my first working for RL Solutions, a software company which provides solutions for the healthcare sector. RL have their main office in Toronto, Canada (checkout the pictures on their careers site). I couldn't find a bus that would travel that far each day, so (sensibly) I've joined the development team based in their Adelaide office.

Backpack with RL Solutions logoI get the impression from the four interviews I had before being offered the position (including with Sanjay, the founder and CEO) that RL have definite ideas about the kind of people they want to hire (not just looking for technical expertise). One of the things that appealed to me was the approach RL is taking in creating a modern, mature, healthy, fun and social work environment. That seems to manifest itself in a number of ways (some just relevant to Toronto or Adelaide and some in common) and I think it's a really positive thing.

My first few days have been spent getting to know the other Adelaide staff (helped in no small way by going out to lunch together on my first day), working through the company's induction programme (they are pretty organised around this), and starting to familiarise myself with the application and codebase that I'll be calling home.

I will also say it is nice to work in a modern building again – one where you don't have nagging doubts that the lifts will deliver you to the floor you requested, and that (a bonus for occasional bike commuters) has shower facilities! I'm still in the CBD though, so no changes to my daily commute.

A nice surprise was the 'welcome' pack waiting on my desk on my first day – including a company-branded backpack.

It's going to be an interesting time, especially learning a whole new business (hospitals etc.) – quite a contrast to my previous industry areas of commodity handling and higher education online teaching and learning. It might prove quite useful to be married to someone with a nursing background, not to mention that our family seem to be rather regular consumers of the health system!

I'm looking forward to it Smile

Saturday, 27 September 2014

The Grand Final

Riders having a break on the way to Outer HarbourYesterday was my last in the office at Eka (formerly MatrixGroup). It was great to catch up with everyone one last time after just over 3 years being on staff. A few final handovers, farewell lunch, attending and presenting at my final Developer meeting and monthly company meeting. I'll miss working with the people there, but I'd decided it was time to move on.
In the meantime, I'm taking a short break. Time to relax, get some kms on the bike, enjoy Adelaide's beautiful spring weather, one or two jobs around the house and do some family things for the first week of the school holidays.
After that I'll be starting something new – more about that in a couple of weeks time!
The photo is from my ride on Tuesday with the Mud, Sweat & Gears blokes heading to Outer Harbour. That turned out to be a handy 93km round trip! I must be doing ok as I pulled up pretty well. It is pretty flat for most of the ride, which probably helped.
(Oh yes, it's also the AFL Grand Final today)

Friday, 19 September 2014

Beware of Invoke-WebRequest in PowerShell DSC

PowerShell has a handy cmdlet named Invoke-WebRequest. I was making use of this in a Script resource as part of a DSC script.

The weird thing was that most of the time it worked, but sometimes the DSC script hung, and as best I could tell, it was within the Script resource that was calling Invoke-WebRequest, but I couldn’t understand why.

Eventually on one particular server, I was able to cause something surprising to happen – calling Invoke-WebRequest caused a modal dialog to appear. The interesting thing was that the server had Internet Explorer Enhanced Security Configuration enabled. Not surprisingly that’s the default for Windows Server.

I posted a question to Stack Overflow and a comment added to the answer made me realise what is actually going on.

I had naively assumed that Invoke-WebRequest is just a nice wrapper around the .NET Framework’s WebClient class, but it turns out it is a bit more than that. It also appears to reference IE-related code.

If you're curious as to what Invoke-WebRequest actually does, then fire up your favourite IL decompiler and point it at C:\Windows\Microsoft.NET\assembly\GAC_MSIL\Microsoft.PowerShell.Commands.Utility\v4.0_3.0.0.0__31bf3856ad364e35\Microsoft.PowerShell.Commands.Utility.dll (that's the path I found the full assembly at).

While the implementation of Invoke-WebRequest actually uses System.Net.WebRequest, it also creates an instance of the IHTMLDocument2 COM object, and I suspect this is the trigger that causes the IE warning to appear.

So if you just want to hit a web address without requiring all the extra features of IE processing, just call either WebClient or WebRequest directly from PowerShell, or Use Invoke-WebRequest but probably not in a 'headless' environment.

Friday, 5 September 2014

Structured JavaScript within ASP.NET MVC

First off, run (don't walk) and go and register for next week's ADNUG talk.

Done that?

Great, I'll see next Wednesday evening!

What? You need more convincing? Ok..

I've worked with Ben Laan for a number of years now and I'd have to say he's probably one of THE best developers I know around the place. He seriously knows his stuff, and is just as comfortable optimising a SQL query on the back-end as he is tweaking CSS layout in the frond-end UI. So I was really pleased when he agreed to come and speak at next week's Adelaide .NET User Group (ADNUG).

To quote from the presentation summary:

Modern web development calls for more JavaScript than ever before. Loose, unorganised script files are no longer acceptable – or sometimes manageable. It is important to ensure those scripts are logically organised, structured, and testable, to ensure code quality.

This presentation will review techniques for organising code to meet these goals within an ASP.NET MVC context using RequireJs – a system for dependency management and Qunit – a unit test framework build by the JQuery team.

Ben's been living and breathing this stuff recently, so I know it's going to be a really good evening. Even if you don't do .NET I think you'll pick up a lot of tips on the writing better JavaScript.

So now I've convinced you, go and register and I'll see you at there Smile

ADNUG meets monthly on the second Wednesday of the month, at Marcellina Adelaide (273 Hindley St, Adelaide). Pizza from 6pm followed by presentation(s), finishing around 7.30pm

Tuesday, 2 September 2014

An inspiring afternoon

This afternoon I attended a funeral. The church was packed with friends and family, I have to say it was one of the best celebrations of someone’s life that I’ve been privileged to attend.

Yes, there was sadness and grief, but overwhelmingly a sense of joy of a life well lived - a passionate husband, father, and faithful man of God.

In his late 50’s, John was not an old man when he passed away last week, but the impact his life and love for others will continue to be felt for years to come.

Sunday, 3 August 2014

Adelaide Windows User Group - PowerShell 301

Some more PowerShell from me, this time at this week's meeting of the Adelaide Windows User Group:

If you're not automating repetitive tasks with PowerShell, you're probably doing it wrong! In this presentation, after a quick language recap, we'll look at a number of best practices that will make your scripts even better. We'll look at tips for reliability, ease of use and making your scripts work just like the built-in cmdlets.
To top things off, we'll also give a brief overview of PowerShell 4.0's new Desired State Configuration feature.

Yes, it's similar to the talk I did at the .NET Group last month, but instead of covering hosting PowerShell in your own app, we'll spend a bit more time looking at DSC.

The group meets this Tuesday August 5th 2014 12-1pm at Microsoft Adelaide, Level 12, Aurora Building, 147 Pirie Street, Adelaide.

RSVP to Pete at [email protected] if you plan on coming. It would be great to see you there!

Monday, 14 July 2014

Disabling NO_CI using 2013 build process templates

Like Philipp, I just noticed that the new simplified 2013 build templates still don't provide an obvious way to prevent a gated checkin build from appending "**NO_CI**" to the checkin comment, preventing subsequent continuous integration or rolling builds from running.

I had a look around and discovered that rather than the old SyncWorkspace activity, the new TfGetSources activity looks like the right place to go to:

image

I was slightly confused, as reviewing the current class documentation doesn't list the property. And it turns out that indeed for TFS 2013 RTM, this property didn't exist (I found this out the hard way – a workflow that references that property will fail when run on such an environment).

Comparing the two C:\Program Files\Microsoft Team Foundation Server 12.0\Tools\Microsoft.TeamFoundation.Build.Activities.dll files (from two different machines) in Reflector reveals the following:

2013 RTM (File version 12.0.21005.1)
image

2013 Update 2 (File version 12.0.30324.0)
image

A useful change introduced in Update 2.

Saturday, 12 July 2014

Dell XPS 1645, Windows 8.1 and Bluetooth

My trusty Dell laptop is still going strong 4 years on. It's showing signs of being well used - the screen is a bit scratched in places, most of the rubber feet have fallen off and the battery doesn't last as long as it used to, but it does the job.

Until recently I hadn't really needed to use any Bluetooth devices, and it was then that I realised that Bluetooth had somehow disappeared. The Bluetooth status light on the front of the case would blink briefly when booting up but then stay off, and there was no Bluetooth icon in the Windows system tray. I'm sure these used to be there originally! A bit of Googling revealed that it was probably upgrading to Windows 8/8.1 that would have disabled it, due to out-dated/incompatible drivers.

I downloaded the latest Dell Wireless 370 Bluetooth Minicard Application, but after it self-extracted, the installer was prevented from running by the Windows Program Compatibility Assistant. Sometimes you get the option to proceed with caution, but in this case not.. Or so it seemed.

Window Program Compatibility Assistant warning dialog

Next, I wondered if I could get newer drivers directly from Broadcom? Well yes you can – from http://www.broadcom.com/support/bluetooth/update.php, but after downloading and running the app it wanted to see the existing Bluetooth device (as it presumably then goes and downloads specific drivers for your devices). But that's the problem, I can't get the device working in the first place!

I came across this post - http://www.wiknix.com/solved-bluetooth-device-not-working-in-windows-8/ which at first glance looked like one of those annoying content aggregation sites, but in this case either the site is legitimate, or at least the instructions were valid. To repeat the relevant steps here:

  1. Go to C:\dell\drivers\R226750\R226750\Win64
  2. Run BtwMM.exe
  3. Run Inst.exe

This time, the drivers installed and bingo, I had Bluetooth devices appearing!

Figuring there's probably a good reason that Windows wasn't keen on these older drivers, I then re-tried the Broadcom Software Update application.

Broadcom Bluetooth Software Download application screenshot

This time, it detected the existing Bluetooth devices and so could proceed to download and update the drivers to newer versions (that apparently do properly support Windows 8/8.1).

Rebooting, I noticed that now just a 'generic' Bluetooth device was listed in Device Manager. Right-clicking on this and choosing Update Driver Software, it then updated the driver back to the Dell Wireless 370 Bluetooth Mini-card (version 12.0.0.8047)

Device Manager now looks like this (yes, my laptop is named 'Clarabel' Smile)

Windows Device Manager, showing Bluetooth devices

And there's the Bluetooth icon in the system tray again:

Windows System Tray showing Bluetooth icon

We're good to go!

Monday, 7 July 2014

SSDT BI Install Logs

A short note for my reference. When you install SQL Server Data Tools – Business Intelligence for Visual Studio 2013, the installer writes a log file to a folder under C:\Program Files (x86)\Microsoft SQL Server\120\Setup Bootstrap\Log\

Handy if you’re trying to install it remotely or via an unattended install file and need to diagnose any errors.

Monday, 30 June 2014

ADNUG–PowerShell for Developers

I'm presenting at the July meeting of the Adelaide .NET User Group.

If you're not automating repetitive tasks with PowerShell, you're probably doing it wrong! In this presentation I will give a quick introduction to PowerShell (including some recommended practices) and then dive deeper into how you can use PowerShell as part of your TFS build process and how you can even host PowerShell in your own .NET applications.

6pm, Wednesday 9th July 2014

Marcellina Adelaide
273 Hindley Street, (Cnr Gray St) Adelaide

($5 for pizza, free if you're an ADNUG member)

Register via the ACS Events site

Hope to see you there!

Tuesday, 10 June 2014

Lumia 920–Stuck in ‘headphones’ mode

Last month after watching the demos from the Microsoft Build conference on the updates to Windows Phone, I decided to take the plunge and update my phone to Windows Phone 8.1. All was going well and some of the new features were really nice – improved keyboard, the notification centre, and VPN support to name a few.

Then all of a sudden a few weeks later my handset wouldn't acknowledge that my headphones were no longer plugged in. It thought they were always plugged in, so didn't play audio through the speaker – making receiving phone calls tricky as you either had to switch the call to 'hands free', or to quickly plug the headphones back in.

A few others seemed to be in the same boat, but subsequent updates for 8.1 didn't resolve the issue. The original reporter then sent his phone off to be checked under warranty. I decided to do the same – for while the problem happened after I'd upgraded to 8.1, there don't seem to be heaps of people with the same problem, so maybe it was more a coincidence and just a regular mechanical fault with the headphone jack.

The only tricky bit was proving to Nokia that it was my phone (I'd won it from Microsoft so I didn't have a receipt). After a bit of email tag and a few phone calls they were finally convinced and I posted my handset off to Sydney.

Before being sent off to Nokia Care, I was asked to use the Nokia Software Recovery Tool. This had the interesting effect of downgrading the firmware and OS back to 8.0 (and didn't fix the audio problem, which increased my suspicions that the problem was not software-based)

Here's the details before it was posted off:

imagewp_ss_20140530_0002

Today I finally got it back. They'd replaced the audio jack and the USB jack. Looks like they re-flashed the firmware with the Australian ‘country’ variant of the Lumia Black Update (3051.40000.1349.0007) – Probably better to have ‘RM-821_apac_australia_new_zealand_304’ instead of ‘RM-821_eu_euro1_425’ I suppose.

imagewp_ss_20140610_0002

And yes, the audio is now working!

While my phone was being serviced, I dug up my trusty old Samsung 'dumb' handset and after visiting Vodafone to get a normal-sized SIM I at least was contactable on my mobile (if not online). Conveniently, Vodafone now give out SIMs that you can pop-out the middle to get a micro-SIM, so I didn't need to go back to the Vodafone shop a second time.

WP_20140610_001

Also, thanks to the Windows Phone Backup feature, I am restoring all my apps and settings so my phone is basically back to how it was before all the dramas started! Very convenient.

Next step, to the latest Windows Phone 8.1 release. With a new audio jack fitted, I'm hoping there will be no more issues.

imagewp_ss_20140610_0002 1

Sunday, 25 May 2014

PowerShell Wix Extension

I've looked, but I couldn't find anyone who'd implemented a Wix Extension that would allow running PowerShell scripts. So I've spent a few hours this weekend writing one (and learned a bit more about Wix and MSIs along the way).

This extension allows you to run script from a file that is included in the MSI, or inline script (inside a CDATA section).

By hosting PowerShell in the custom actions, scripts also get access to the $session variable (which is of type Microsoft.Deployment.WindowsInstaller.Session), so you can call $session.Log("Running this") and it will add "Running This" to the MSI log!

Here's an example of what you can do:

<?xml version="1.0" encoding="UTF-8"?>
<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi" xmlns:powershell="http://schemas.gardiner.net.au/PowerShellWixExtensionSchema">
  <Product Id="*" Name="PowerShellWixTest" Language="1033" Version="1.0.0.0" Manufacturer="David Gardiner" UpgradeCode="c61298af-d8c9-4179-903f-f42fa69b59ad">
    <Package InstallerVersion="200" Compressed="yes" InstallScope="perMachine" />

    <MajorUpgrade DowngradeErrorMessage="A newer version of [ProductName] is already installed." />
    <MediaTemplate />

    <Feature Id="ProductFeature" Title="PowerShellWixTest" Level="1">
      <ComponentGroupRef Id="ProductComponents" />
    </Feature>

    <powershell:File Id="PSFile1" File="[#TestPs1]" Arguments="&quot;First Argument&quot; 2"/>

    <powershell:Script Id="Script2">
      <![CDATA[
        
        # Write-Host "Number 2";
        
        for ($i = 1; $i -le 100; $i++) 
        { 
          Write-Progress -Activity "Activity" -Status "Status $i% complete" -CurrentOperation "Operation $i" -PercentComplete $i
          Start-Sleep -Milliseconds 5 
        }
        
        ]]>
    </powershell:Script>
    
    <UI>
      <TextStyle Id="WixUI_Font_Normal" FaceName="Tahoma" Size="8" />
      <TextStyle Id="WixUI_Font_Bigger" FaceName="Tahoma" Size="12" />
      <TextStyle Id="WixUI_Font_Title" FaceName="Tahoma" Size="9" Bold="yes" />

      <Property Id="DefaultUIFont" Value="WixUI_Font_Normal" />
      <Property Id="WixUI_Mode" Value="Minimal" />

      <DialogRef Id="ErrorDlg" />
      <DialogRef Id="FatalError" />
      <DialogRef Id="FilesInUse" />
      <DialogRef Id="ProgressDlg2" />
      <DialogRef Id="UserExit" />

      <Publish Dialog="ExitDialog" Control="Finish" Event="EndDialog" Value="Return" Order="999">1</Publish>

      <Property Id="ARPNOMODIFY" Value="1" />
    </UI>

    <UIRef Id="WixUI_Common" />
  </Product>

  <Fragment>
    <Directory Id="TARGETDIR" Name="SourceDir">
      <Directory Id="ProgramFilesFolder">
        <Directory Id="INSTALLFOLDER" Name="PowerShellWixTest" />
      </Directory>
    </Directory>
  </Fragment>

  <Fragment>
    <ComponentGroup Id="ProductComponents" Directory="INSTALLFOLDER">
      <Component Id="ProductComponent">
        <File Id="TestPs1" Source="Test.ps1" KeyPath="yes" />
      </Component>
    </ComponentGroup>
  </Fragment>
</Wix>

The code and releases are hosted on GitHub - https://github.com/flcdrg/PowerShellWixExtension

Development resources

Friday, 9 May 2014

Aussie Forecast

My latest app for Windows Phone is now available in the store – Aussie Forecast!

Aussie Forecast Lock Screen

Windows Phone 8 supports apps displaying custom information on the lock screen. The Bing Weather app is a nice example, but I was frustrated by the inaccurate forecast data that it was using. Not the first time I've seen this problem.

So I thought I'd create my own app that uses the Australian Bureau of Meteorology's data to display the forecast for a selected location. You can optionally choose to have the forecast displayed on your phone's lock screen, and a background task runs at regular intervals to keep the information current.

Application main page screenshotSettings screen

Future enhancements will include allowing a user-selected photo for the background image or the daily Bing Photo.

If you've got a Windows Phone 8 device, then please try it out!

Download from the Windows Phone Store

Sunday, 4 May 2014

Using BugSense for Windows Phone with Caliburn.Micro

BugSense is a 3rd party service I came across recently being promoted on Nokia's (now Microsoft's) DVLUP site. They provide aggregation and reporting of errors from your apps.

All of the usual platforms are supported, and conveniently they provide NuGet packages to facilitate integrating with Windows Phone 7, 8 and Windows Store apps.

I like using Caliburn Micro (CM) for most of my Windows Phone apps to help with using the MVVM pattern, and one of the requirements for using CM is to strip out the contents of the App.xaml.cs file's constructor, leaving just

public App()
{
    // Standard XAML initialization
    InitializeComponent();
}

The BugSense instructions however assume you're using a regular Windows Phone project that has the original App.xaml.cs contents. The workaround I've settled on is to add the BugSense code to the body of the Configure method in the CM AppBootstrapper class.

First, add the BugSense namespaces:

using BugSense;
using BugSense.Core.Model;

Then initialise BugSense (replacing API_KEY with the key displayed when you click on 'Help me integrate' on the BugSense site:

protected override void Configure()
{
    // Initialize BugSense
    BugSenseHandler.Instance.InitAndStartSession(new ExceptionManager(App.Current), RootFrame, "API_KEY");

You might also wish to add logging of handled exceptions too:

catch (Exception ex)
{
    BugSenseLogResult logResult = BugSenseHandler.Instance.LogException(ex);

    // Examine the ResultState to determine whether it was successful.
    Debug.WriteLine("Result: {0}", logResult.ResultState.ToString());

    Debug.WriteLine(ex);
}

In a future post I hope to describe logging exceptions for background tasks.

Sunday, 6 April 2014

var article = new State<TheUnion>();

What an interesting time to be a .NET developer!

In the last week, Microsoft held its now annual Build conference and announced a whole bunch of new product offerings and features. For most of us who can’t get there in person, downloading and watching the session videos is almost as good. All of the keynote and session videos are (or soon will be) available on the Channel 9 Build 2014 event page

Build doesn’t just focus on .NET – it tends to cover developer topics that relates to any Microsoft technology – Windows desktop, Phone, Web and Azure (cloud).

Open sourcing

I remember having a conversation with Dan Shearer many years ago. Dan is a big advocate of open source software. I surprised him at the time by telling him about this XML-based installer software that Microsoft had made open source and hosted on SourceForge (10 years ago). I think this was still when other parts of Microsoft were still quite anti-open source. 10 years on, things have changed quite a lot.

We have not only the OuterCurve Foundation, but now just announced at the Build conference, the .NET Foundation to promote and ‘steward’ a collection of open-source technologies for .NET. Curious that they created a second foundation, but what ever gets the job done I guess.

The biggest thing in this area for me was the announcement that the new .NET C# and VB compilers (aka ‘Roslyn’) would become open source. They’re up now on CodePlex - http://roslyn.codeplex.com/ (and yes, they’re taking pull requests too)

My how things have changed!

8.1

Windows 8.1 Update 1 is out, and Windows Phone 8.1 is coming in the next few months. Apart from the new phone features, I think the big news here is the new “Universal” applications that make it simpler to develop a single app that works on both Windows Phone and Windows Store (aka Metro). Laurent Bugnion has more info on his blog. This is nice – though it only works for 8.1 so it doesn’t necessarily solve the problem of supporting older platforms (eg. Windows Phone 7 or the current Windows Phone 8 before the upgrade is released)

Azure

Watching the Day 2 keynote with Scott Guthrie impressed me with how much is going on in Azure land. I feel like I really need to get more familiar with this stuff.

Other highlights

  • TypeScript 1.0 announced
  • Cortana – like Siri but supposedly better
  • .NET native compiler
  • Seeing an iPhone and a Mac both used in demos – I don’t particular care about these devices but I know a lot of people do.

That will do for now – I’ve got some more videos to watch (if our monthly internet quota doesn’t get used up – I already managed to lose all my phone’s data quota when it decided to use 3G instead of the home wireless to stream the keynote Sad smile)

Friday, 7 March 2014

Farewell MCT

I first became a Microsoft Certified Trainer back when I was working at LobsterPot Solutions. Teaching is something I quite enjoy, though the opportunities are limited. The only times I've been using my MCT status in the last few years was to be able to attend the Microsoft TechEd conferences as a hands-on labs trainer.

Recently, Microsoft announced some changes to the MCT programme, including that MCTs must teach at least one course a year, and that receive a training quality score (feedback) of at least 6.

As it's been a few years since I last taught a course, I won't be able to renew my MCT this year. They have introduced an 'MCT Alumi' programme for inactive trainers, which I would qualify for, but I haven't decided if there's value in me doing that.

Sunday, 2 February 2014

Extending WinForms controls

I've been looking at ways to extend and enhance .NET WinForms controls recently and thought I'd summarise what I've found/learned so far.

Inheritance

The most obvious way to extend a control is to create a new class that inherits from the existing class. You then have full access to add new properties and methods and access any protected methods from the base class.

It does mean that if you've already used the control in your application, you're going to have to replace references to the base class with your new class – not always easy.

IExtenderProvider

Properties window showing Tooltip propertyAnother option is to create a class that implements the IExtenderProvider interface. You can then create a component that can be added to a form or user control that extends specific types. An example of this that ships in the framework is the ToolTip class. When you drag this control onto a form it doesn't add a visible control to the design surface. Instead it adds a new ToolTip property to appropriate controls on the same form.


Custom ComponentResourceManager

Visual Studio designer showing properties window with Localizable set to trueA more specific area of WinForms controls that you might want to customise is the localisation support. Localisation for controls on a form is enabled by setting the Localizable property of the form to true. This also alters the designer-generated InitializeComponent method to add a new resources variable of type System.ComponentModel.ComponentResourceManager. This allows you to use .resx resource files to load locale-specific values for properties. This is the standard way that you would provide alternate language translations for your application.

A question on Stack Overflow asked about replacing this implementation with another that could load resources from an alternate location (such as an XML file or a database). The accepted answer pointed to some samples from Guy Smith-Ferrier's book, .NET Internationalization: The Developer's Guide to Building Global Windows and Web Applications.

Impressively, even though the book was published in 2006 Guy has been releasing regular updates to the code samples at http://www.dotneti18n.com/Downloads.aspx. His sample for a custom ComponentResourceManager includes a ResourceManagerSetter class that has the DesignerSeralizer attribute. This was new to me, but it turns out this is the mechanism that generates the code that appears in a forms's .Designer.cs file. This uses the CodeDom to generate code that inserts the replacement ComponentResourceManager instance.

private void InitializeComponent()
{
    System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(UserControl1));
    this.resourceManagerSetter1 = new Internationalization.Resources.ResourceManagerSetter();
    this.label1 = new System.Windows.Forms.Label();
    this.SuspendLayout();
    Internationalization.Resources.ResourceManagerProvider.GetResourceManager(typeof(UserControl1), out resources);
    // 
    // label1
    // 
    resources.ApplyResources(this.label1, "label1");
    this.label1.Name = "label1";
    // 

Using CodeDom means that the code is generated for the appropriate language automatically. The only requirement is that this component must be the first one added to the form. If you're adding this to an existing form with controls, just go to the Designer.cs file and move the line calls the constructor to the top of the InitializeComponent method. (The order of the calls to the constructors seems to determine the order in which the serialized code generators are called)

You can see from the code sample above that the original instantiation is still there, but is effectively replaced by the call to the GetResmourceManager method.

MSDN has more info on Globalizing Windows Forms.

Saturday, 25 January 2014

Tour Down Under 2014

We made it!

Me and Dad, about to head for the start at UnleyI'm glad to report that unlike last year, my back was behaving itself and yesterday I was able to take part in the Bupa Challenge Tour with my Dad. The Challenge Tour is a chance to ride the same route that the professionals do for one day of the Tour Down Under. Like previous years, we rode as part of the Mud, Sweat & Gears team.


Riders, Looking north up King William RdWe rode the full course of 154km from Unley to Victor Harbor. That's the longest distance I think I've ever ridden, and boy did my feet and my behind know about it – especially the last 30km or so! It took just under 8 hours (7:54 according to the Endomondo app I used on my phone), which included time at the rest stops.

The start of the ride took us up the South-Eastern Freeway through the Heysen Tunnels. Normally cyclists aren't allowed along here, so that was quite a novelty – though we agreed that the tunnels themselves are quite stuffy.

The weather this year was fantastic. It was a little drizzley early in the morning, but then remained comfortably cool for most of the day. It was overcast for most of the morning, which helped a lot. A gentle breeze earlier in the day became a little more blustery towards the end, but not as bad as some years.

We made three stops along the way – at Meadows, Mt Compass and Yankalilla. A chance to refill drink bottles with various colours of Powerade (each stop seemed to have a different colour) and grab a banana and fruit cake to refuel.

This year for the first time they scanned the RFID tags on our bikes as we progressed through the route. You could then log in to a website to obtain the results. Here are mine:

Split TOD Time
Unley 06:42 am 00:12:16
Unley Backup 07:09 am 00:39:30
Stirling 07:53 am 01:23:13
Meadows 09:03 am 02:33:57
Mt Compass 10:30 am 04:00:13
KOM 11:48 am 05:18:17
Yankalilla 01:13 pm 06:43:55
Finish 02:37 pm 08:07:25

Route map from Unley to Victor Harbor

The ride started at 6.30am, but you as can see it took us 12 minutes to pass through the start – not surprising as there were thousands of riders there.

Highlights:

  • Repeatedly being overtaken by former UniSA colleague Mandy (apparently I'm quite conspicuous on a bike, even amongst 6,600 other similarly attired cyclists)
  • Well run food and drink stops
  • Watching the pros finish in a blaze of colour
  • Finishing

Lowlights

  • They'd temporarily closed the lunch station as the pros were approaching the finish line and there just a few salad roles in a tray. I gather earlier finishers had a better selection. We didn't starve, but it didn't seem to be very organised.
  • I wonder if there's such thing as a saddle that's comfortable even after 100kms. I don't think I have one Smile

Oddlights:

  • Lemons as a choice of fruit at the food stops. Didn't seem to be a lot of takers.

Team work

After the ride – waiting for the Pros (photo by Fiona)

Keep your focus on the goal

Grimacing Greipel, 150m to go before he won the stage (photo by Fiona)

Special thanks to Narelle's parents Rick and Margaret, who drove us to the start very early in the morning, and then met us at the finish to take me and our bikes home again.