This bit me recently. To quote Eric Lippert (last paragraph):

Remember that with LINQ the result of a query expression is a query that can deliver the results when asked, not the results of the query.
This code will result in the PropertyChanged event handler never being called:

    var items = (from item in MethodThatGetsItemsAsEnumerable()
                select new ViewModelEntity(item));

    foreach (var item in items)
    {
        item.PropertyChanged += item_PropertyChanged;
    }

    this.Items = new ObservableCollection<ViewModelEntity>(items);

The correct code is, of course:

    var items = (from item in MethodThatGetsItemsAsEnumerable()
                select new ViewModelEntity(item)).ToList();

    foreach (var item in items)
    {
        item.PropertyChanged += item_PropertyChanged;
    }

    this.Items = new ObservableCollection<ViewModelEntity>(items);

The first code will result in MethodThatGetsItemsAsEnumerable being called twice, once when items is iterated over in the foreach and once when the ObservableCollection is constructed, ergo the item's that had item_PropertyChanged attached have long since disappeared. The ToList() in the second version is the solution as it turns the query into the results of the query.

Amazon order tracking glitch

|
Amazon.co.uk seem to have a small glitch in their "Your Orders" page when it comes to order tracking, nothing world ending, but certainly mildly misleading:
Amazon Order History tracking issue
My package is in Wednesbury and out for delivery, to a delivery address between Southampton and Portsmouth? I think not, unless the driver is driving a *very* long way! The Citylink site shows a more accurate view:

Citylink Order Tracking page

Outlook 2010 Beta - Still not implemented

|
Previously in the saga: Outlook 2010 Beta - "Not Implemented" on Send/Receive.

It would appear that problems with Outlook complaining that something is "Not Implemented" are more widespread than I thought when I encountered the issue. Someone on the Technet forums has encountered the "Not Implemented" issue, with what looks like a slightly different set of circumstances, and another person on the Zimbra forums is also encountering the error.

I mentioned the issue, along with my solution, over on the the Office 2010 Engineering blog, but have yet to see anyone else comment there that they've encountered the issue, or any MS bods acknolwedge that it's a known issue. I cross-posted the comment to the Outlook blog so anyone who encounters the problem would stand a better chance of getting to try my solution, but it looks like the comment wasn't released :(

I have to say, this is the only bug I've found with Outlook 2010 so far, though!

DataTable Key/Value columns to Dictionary

|
There are undoubtedly more elegant ways to do this using LINQ, but to quickly and easily take the key (int) and value (string) columns from a DataTable and turn them into a Dictionary<int, string>, the following method has come in handy recently:

        public static Dictionary<int, string> GetAsDictionary(DataTable data, string keyField, string valueField)
        {
            Dictionary<int, string> dictionary = new Dictionary<int, string>();

            foreach (DataRow row in data.Rows)
            {
                dictionary.Add(Convert.ToInt32(row[keyField]), Convert.ToString(row[valueField]));
            }

            return dictionary;
        }

Outlook 2010 Beta - "Not Implemented" on Send/Receive

| | Comments (9)
I yesterday installed the Office 2010 beta and almost immediately came across a fairly serious "bug". It's debatable whether the bug was caused by Microsoft (i.e. a fault on the part of Office) or by myself, as you'll see when I explain what I did and what the solution is.

What I did.

1 - Installed Office 2010 x86 as a side-by-side install with 2007 (on Windows 7 x86).
2 - Ignored the "reboot now" prompt as I needed to open and print a word document
3 - Opened the document in Word 2007
4 - Waited whilst Office 2007 setup did *something*
5 - Printed document and closed word.
6 - Rebooted
7 - Loaded Outlook 2010

This is where my problems began. I received an error message about "Default Programs" over the top of the splash screen, the "backstage" screen was perpetually telling me that my files were being upgraded and that I needed to update the "Connector". Also, when clicking "Send/Receive" I received a "Not Implemented" modal dialog. It's also worth mentioning that Outlook was absent from the Default Programs control panel applet.

How I solved it.

1 - Uninstalled Office 2010
2 - Rebooted
3 - Re-installed Office 2010
4 - Rebooted
5 - Loaded Outlook 2010

Et Voila, problem solved.

Opera - As delusional as ever..!

|
From: Opera applauds scepticism on MS browser pledge (on The Register).

The last paragraph:
"For the installed base of IE users, Windows updates and IE updates should come preloaded with other browsers and a ballot screen. The ballot screen with a choice of at least five browsers should also be provided to customers who buy Windows through the retail channel to upgrade their PCs."
Errr, whaaaat!? Internet Explorer, Firefox, Safari, Chrome, Opera. There, that's five browsers named, and the last 3 are marginal (at the moment). The only use I've ever found for Opera as a browser is on my mobile. On the PC it's unintuitive and crap. Yes, crap. I primarily use Firefox, followed by IE. Safari I wouldn't use if I was paid (unless it was a *lot* of money) thanks to the way Apple Update used to (and may still) treat it. All that non-withstanding, surely if Microsoft are going to be required to do this, surely Apple (as the monopoly O/S provider for Mac') should be required to do the same?

Not that it'll make the blindest bit of difference though; 99% of home computer users don't know a massive amount about computers, so they'll answer the question "How do I get on the internet?" with "I'll choose the thing called Internet Explorer". Business users will, for the most part, have their access to a browser decided by Corporate IT, who will inevitably choose IE to ensure compatibility with their web-based LOB applications that have been around for a decade and rely on IE6's odd layout behaviours, or other IE proprietary technologies like ActiveX.

Yet another wonderful waste of money perpetrated by the EU, thank you very much one and all for dumping money I've paid in taxes down the drain. *Le sigh*

MySql ServerName.Log file size

|
A quick and dirty hack (written in C#) to solve the issue of MySql query log files getting huuuge:

System.ServiceProcess.ServiceController sc = new ServiceController("mysql", "servername");
sc.Stop();
Console.WriteLine("Stopping");
sc.WaitForStatus(ServiceControllerStatus.Stopped, new TimeSpan(0, 0, 30));
Console.WriteLine("Stopped");
System.IO.File.Delete(@"\\servername\C$\Program Files\MySQL\MySQL Server 5.0\data\ServerName.log");
Console.WriteLine("Starting");
sc.Start();
sc.WaitForStatus(ServiceControllerStatus.Running, new TimeSpan(0, 0, 30));
Console.WriteLine("Started");
I have this compiled into a CruiseControl task that runs at 7am every day, no more massive log files and a lot easier than trying to decipher the MySql documentation. Plus, I've got some other odds and ends of maintenance that I've shoe-horned in. Not necessarily elegant, but it works!

Why "int foo = 0;" is pointless in variable declarations

|
From: What does the optimize switch do?

Part of the way down:

* We omit generating code for things like int foo = 0; because we know that the memory allocator will initialize fields to default values.
The key there is that "the memory allocator will initialize fields to default values" ... see, there's really no point in setting fields to their default values, it's just code clutter. The compiler throws it away, and even if it didn't, the memory allocator would make it entirely pointless!

Coolite - File Upload Dialog & other breaking changes

|
I think I've mentioned the custom File Upload Dialog for Coolite previously which sadly doesn't seem to work with Coolite v0.8 due to a breaking change that's not mentioned in the Version 0.8.0 -BREAKING CHANGES forum post. In summary, the ParameterCollection object no longer has a "ToJsonObject" method, but this has been replaced/renamed with "ToJson". Changing the source for the file upload dialog and re-compiling resolves this.

I also found that, as mentioned in ScriptContainer location not honoured in 0.8 against 0.7, the behaviour of the Coolite ScriptContainer has changed as it now seems to have been split-out into the ScriptContainer and StyleContainer controls. Easily solved, but no less annoying that I had to spend time doing so.

extJs: Combobox .getValue oddity - 2 (The "Solution")

|
Previously: extJs: Combobox .getValue oddity

Here's a quick-hacky solution (a better one would be to ensure your combobox's are selection-only):

Ext.override(Ext.form.ComboBox, {
    getValue: function()
    {
        return this.value;
    }
    });

Coolite documentation

| | Comments (3)
It might only have been auto-gen'd from the sourcecode, but it's still better than nothing: Coolite Toolkit Documentation. The quality of (or lack of) documentation seems to be a fairly frequent complaint on the Coolite forums, and as there's not quite always a one-to-one mapping between Coolite and extJs, looking at the (comprehensive) extJs documentation isn't always useful.

In addition, to anyone working with Coolite, I would strongly recommend downloading the sourcecode and reviewing it when you come across strange/unexpected/confusing behaviours. It's not that difficult to step-through and get a fairly good idea of what's going on!

extJs: Combobox .getValue oddity

| | Comments (2)
At least in extJs version 2.2.1 (the version baked into Coolite v0.8), the getValue function on the Ext.form.ComboBox appears to be thus:

function()
{
  if (this.valueField&&this.forceSelection)
  {
    return typeof this.value!="undefined"?this.value:"";
  }
  else
  {
    return Ext.form.ComboBox.superclass.getValue.call(this);
  }
}
Of interest is the fact that differing code-paths are taken based on the "forceSelection" property. If it's set (i.e. thou shalt choose something from this combo and not enter free-text), then the .value property is used as the return value of the call to getValue, otherwise a call is made to superclass.getValue, which returns something quite entirely different!

Instead of, as expected, returning the "key" value, it returns the displayed value. This is thanks to superclass.getValue being defined as:

function()
{
  if (!this.rendered)
  {
    return this.value;
  }
  var v=this.el.getValue();
  if (v===this.emptyText || v===undefined)
  {
    v='';
  }
  return v;
}
Whilst I've logged this as an "oddity", it is (seemingly) "by-design" as the combo-box allows for user-entered values, which is what the "forceSelection" code-branch causes. That said, I firmly believe that if the "selected value" is one that has been chosen from the contained items, then getValue should return in the same way as it does with forceSelection being false.

A review of "Review: CryptoLicensing for .NET"

| | Comments (1)
The review of CryptoLicensing for .NET that Roy Osherove posted recently was very well written and covered a topic that I've long held a mild level of curiosity around. That topic being protecting code/software that's written using a .net language from a licensing perspective.

There's a whole black-market industry surrounding the cracking of software and irrespective of the legality or ethics of it, I'm pretty sure a lot of people have used cracked software at some point (bonus points and the moral high-ground to those who claim they haven't and are actually telling the truth!). Be it cracked/patched software, a serial number generator, a serial number that everyone's using, there are ways and means. By far the simplest is probably with something like WinRAR that pops up a "Please purchase WinRAR license" dialog box and relies on honesty, with more complex and convoluted solutions like Microsoft's OS licensing that can go horribly wrong if their activation servers have a bad day. Not to mention the "what will happen when" scenario for when Microsoft finally get bored of providing activation servers/services for Windows XP.

The thing that particularly sparked my interest was a comment from Frans Bouma, which could be summed up pretty much as saying "whats the point?", which seems to be a very good question. My opinion is that some form of licensing/activation solution at least raises the bar and reminds people using the software isn't actually free for them to use and do with it what they will. Plus, software that has an "n-day trial" that's expired is likely to get paid for if it's expired and then its use is required. I frequently install software for a single/ocassional task that has a "30 day trial" attached, or similar, and then promptly forget about it. When I then come to perform that task again 6 months later, if the price is right I end up buying it. If not, off comes the software and something else is found.

A fantastic example of this is a project I worked on about 2 years ago, I'd played around with a trial version of some .net data access layer generating software (I can't for the life of me remember what it was, one laptop later and it's not installed - but I have the license key somewhere!) a few months before that for a one-time-use tool I needed to write and then had this project thrown at me with a very tight deadline and no other development resource. I remembered the software, loaded it up, "out of trial", bugger! One credit card transaction later the license key was in my inbox and in the product. So, licensing control software worked for the publisher concerned!

Now, I wonder if there's a trial version of CryptoLicensing available that I can have a play with,....?

MySql - Running a complex script using the .net Connector

|
[The solution was discovered via this entry in the mysql.com forums]

I your MySql script contains code like

"/*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */;"
You'll need to add "Allow User Variables=true" to your connection string. This can be achieved by manually adding it to the string, or, if using a MySqlConnectionStringBuilder, something similar to the following:

var builder = new MySqlConnectionStringBuilder
{
     Database = database,
     Server = Server,
     Password = Password,
     UserID = Username
};
builder.Add("Allow User Variables", true);
Make sure you're using at least version 5.2.6 of the MySql Connector/Net though! The forum posting states that it works with 5.2.2, but it didn't work with the copy of 5.2.2 I hav, but did with 5.2.6.

Other useful links from the forums:
Re: How do i run a *.sql script from my c# environment?

A string of character 'x' the same length as string 'y'

|
... is quite simple in .net, as I found out!

            string title = "My line of text that I'm writing to the console underlined with equals signs";
            Console.WriteLine(title);
            Console.WriteLine(new String('=', title.Length));
Powered by Movable Type 5.04