Monday, February 20, 2006

Stringly Typed Data

The project I am currently working on involves the new SQL Server 2005 Reporting Services. So far, other members of my team have been responsible for the reporting modules but I know I will be working with it soon so I decided to do some preliminary research.

I believe in keeping my blog as a source of positive information and I prefer to post about problems where I have already found a solution I can offer to the community. However, a particular problem I have encountered with Reporting Services does not seem to have a solution, so I hope this post will bring more attention to the problem and perhaps a solution will eventually be provided by Microsoft. This is assuming that this problem is not a result of my inability to find the right documentation.

I am referring to the ReportParameter class in the Microsoft.Reporting.WinForms namespace. This class is used to pass parameters to the Report Server for determining the contents of the report produced. The problem is that the ReportParameter only seems to support String typed parameters. Considering many reports will be based on the results returned by stored procedures in SQL Server I would expect Reporting Services to be using a very similar structure for its input parameters.

With the current structure I cannot pass NULL to a ReportParameter. I would need to use special values such as -1 maybe for an int parameter and the stored procedure would need to be changed to understand that. If I want to be able to distinguish between an empty string and a NULL string I have to go to more effort to choose a special value that won’t be used in my data.

Another filter that I will commonly use for reports is a date filter. The user should be able to choose a start and end date and generate a report with data within that range. With standard Stored Procedure calling, ADO.NET will handle all the necessary converions for passing DateTime parameters in the correct format for the database. With Reporting Services I need to convert the DateTime to a String manually by considering the locale of the user’s computer and the Report Server.

ADO.NET has been built to provide a base level of data classes to suit all types of features and capabilities found in various database engines. There is no reason why Reporting Services should not have been developed the same way, especially considering this is now the second release of the product.

I am interested in reading the comments of others on this topic and if I am wrong about all this can someone please point me in right direction.

Demoted

With Windows XP, I find I don’t need to reinstall my system as often as I did with previous versions. As a result there are large gaps between each installation of Visual Studio and my memory fades during this time.

One of the decisions to be made when you run a fresh install of Visual Studio for the first time is how you want the environment to be configured: General Development, Visual Basic, Visual C#, etc. Your choice here will determine default window positions, menu and toolbar items and keyboard shortcuts among other things. Each time I am faced with this decision I am not sure what I chose last time. Should I use the Visual Basic settings to suit my preferred language or should I use General Development settings so the environment is ready for me to jump around between languages and project types?

When I installed Visual Studio 2005 in November I chose Visual Basic and I have since been annoyed by the difficulty in finding the Build Configuration Manager and the quick Debug/Release chooser on the toolbar. I had assumed that this was a simple change in the UI for VS2005 so I customised the menus and toolbar to include the missing items. I intended to blog about this problem when I first noticed but it was delayed until now.

I was reminded the other day when, wandering through the .NET documentation, I stumbled across a couple of articles about hidden debug commands in the IDE. I was shocked to read that the build menus and toolbars are limited only when Visual Basic is chosen for the environment configuration. Considering in VS2005, Microsoft brought the VB language much more into line with C# and introduced low-end Express Editions for beginners, I was surprised they decided to take a step backwards and hide build configurations from VB users in the Professional version. Just when I thought Visual Basic had been promoted to a first-class language in the .NET range!

For anyone else who was baffled by this change in the new version, here is the MSDN article explaining how to get control of your builds back.
 Sunday, February 19, 2006

The Thermometer Of Success

While I am now doing some serious .NET work I am finding myself blogging more about non-programming topics. I subscribe to many RSS feeds, including the aggregation provided by .NET Developers Blog. I read a post yesterday by Andre Cruz about software for monitoring system temperatures.

 I was accustomed to this kind of system monitoring software being provided with the motherboard drivers for all my desktop computers but my laptop did not include anything like this. Looking at the laptops of different brands used by my colleagues this seems to be a common oversight by laptop manufacturers.

Thankfully, the MobileMeter software mentioned in the blog provides the perfect solution. It utilises ACPI to display all the temperatures available from the system which includes processor and hard drive on my laptop and also several others on other laptops. It also shows current processor speed (I was surprised how low it drops on some of my battery power modes) and even the current battery charge or discharge rate in Watts.

The best feature however is that I can not only set the MobileMeter window to be always on top and very transparent, it will also allow all mouse operations on the window to pass through to underlying objects as though the window wasn’t there at all. This is the best system tool I have encountered since Sysinternal’s Process Explorer.


 Friday, February 17, 2006

The ‘Net Is Getting Tighter

This post isn’t about .NET programming directly but it is about the tools I use when programming. I am quite fond of using batch files to execute common maintenance tasks like archiving source files or performing custom builds. However, sometimes the target folders of the actions within these batch files are located on network shares that are not mapped to a network drive. Most batch commands will happily accept UNC paths as arguments on the command line but the command prompt (cmd.exe) does not support setting the current directory to a UNC path.

I don’t like to map network drives for infrequently accesses shares and I especially don’t like mapping network drives to the hidden x$ administrative shares. A common technique is to call NET USE at the beginning of the batch to temporarily map the share until a call to NET USE /DELETE at the end of the batch cleans it up. Even better though, I found some articles on Microsoft support describing easier methods to achieve the same result.

Knowledge Base article 156276 specifies a registry key that can be changed to enable a UNC path as the current directory but this didn’t seem to work all the time for me. Article 317379 describes the more portable method of using the PUSHD and POPD directory stack commands that will automatically map an unused drive letter to the UNC path and remove it when done.

I also discovered recently that Windows XP has a built in VPN Server feature accessible from the Network Connections folder in Control Panel. Run the New Connection Wizard, select “Set up an advanced connection”, and follow the prompts. It’s scary that I am still discovering new features when I have been using Windows XP since release.

 Thursday, February 09, 2006

The Faulty Default

I haven’t blogged in a while. Some of you may have noticed. Some of you may have rejoiced. I have just started a new job this month after leaving my previous job of almost eight years. I have also been trying to find and purchase a new home for my fiancée and myself. My new job is great but my work with Visual Studio 2005 is exposing me to the many interesting glitches in the .NET framework again.

This week’s gem was encountered while developing a base form to inherit from as a template in several other projects. This base form has a ToolStrip with a collection of standard buttons that will be common to all projects. In VS2005, the ToolStrip and other collection based controls have very limited design-time support in visual inheritance situations. The reasons for this and the associated problems deserve an article of their own that I may write about later.

To workaround this I created a series of properties on the base form to allow some of the standard buttons to be hidden using a simple Boolean property accessible through the designer. Initially I coded these properties to simply map to the ToolStripItem.Visible property on each corresponding button. As all the buttons are visible in the base form, these properties are also naturally true. Unless otherwise specified, the designer will assume that Boolean properties default to false and will only serialize the value of the property to the derived form’s designer code if the value varies from the default. This means that whenever the property is changed to False on the derived form, it doesn’t get serialized and it reverts back to True.

To fix this I tried applying the DefaultValueAttribute to each of the appropriate properties in the base form but the designer still insisted on assuming False was the default. I tried the usual: rebuild the solution, restart Visual Studio, search Google Groups and anything else but nothing helped. I found an older project where I had needed to achieve the same default on a Boolean property and investigated that code. It used the DefaultValueAttribute in the same way but this older project actually worked. I spent quite a while trying to track down the differences and eventually managed to simplify the problem.

Basically if the getter of a Boolean property maps to a private member, a function call, a property on any object or whatever and you use the DefaultValueAttribute to set the default to True it works. If the getter maps to a ToolStripItem.Visible property directly or via nested function calls then the DefaultValueAttribute is ignored. ToolStripItem’s also have an Available property which is effectively equal to Visible with some minor conditions and actually calls the Visible property in it’s implementation, however mapping a Boolean property to ToolStripItem.Available works with the DefaultValueAttribute. As far as I can tell, the only potentially relevant difference between the ToolStripItem.Visible and Available properties is that Visible has the LocalizableAttribute set to true.

According to the documentation the LocalizableAttribute determines whether the designer will serialize the value to code or to a resource file. Considering I simply call the property getter and not inherit from it this should not be a problem but it is the only thing that seems to explain my results. I have built a very simply project to reproduce this strange behaviour and you can download it here. I don’t know whether this is a bug or is by design but it sure is irritating and I’m concerned that it may appear in other situations. I’d be interested if anyone can shed any more light on this issue.