New Article: Converting Numbers to Strings

I’m not keeping up my blog like I should. To try and fix this, I’m going to attack my backlog of “articles to end forum posts”. I’m active on some beginners’ VB .NET forums, and some questions come up very frequently. It’s frustrating when it’s one that requires a lot of explanation like, “Why does setting the property on this class change the property on this other variable?”. I’m going to try and attack one of these each month or (ideally) each week. Maybe by then I’ll be in the habit.

Today’s article: Converting Strings to Numbers. It’s a beginners’ article, so don’t expect anything profound. My main target is newbie VB .NET developers but I threw in some C# information where it behaves differently.

Perilous Parallel.For

I’ve been playing a lot with the Task Parallel Library because I’m really excited about the new Task-Based Asynchronous Pattern. Someone on the VB forum asked a question that was more or less about parallelizing a task, and I endeavored to make an example that compared the performance of some approaches.

When I got to the one that used Parallel.For, I started having some random incorrect results. Here’s some code that reproduces what I was seeing:

using System.Threading.Tasks;
using System.Threading;

static class Class1
    private const int NumberOfValues = 100;

    public static void Main()
        int[] values = new int[NumberOfValues];
        int expectedSum = 0;
        for (int i = 0; i < values.Length; i++)
            values[i] = i;
            expectedSum += i;

        for (int i = 0; i < 10; i++)
            int sum = 0;
            Parallel.For(0, values.Length, (int value) =>
                    sum += value;
            System.Console.WriteLine("{0}/{1}", expectedSum, sum);


The frequency of incorrect results seemed to depend on the presence and length of the Sleep() call. This told me it was most definitely a problem with concurrent access to the sum variable. My first attempt to fix it involved making a class with a lock:

class Sum
    private readonly object LockObject = new object();
    private int _sum;

    public int Sum
            lock(LockObject) { return _sum; }
            lock(LockObject) { _sum = value; }

It didn’t help. This is where I actually started converting the project to C# and planning out a StackOverflow post, but after a few more minutes of thought I figured out what was happening.

When sum += value executes, it looks like one atomic step, but it’s not. It has to execute in at least two steps: it must fetch the current value of sum, it must apply the + operator to that result, then it must assign the result to sum. There is a potential for some thread to assign a new value to sum after some other thread has retrieved it; this will cause some results to be lost. The Sum class above didn’t solve this because the thread synchronization only blocks concurrent access to the get and set individually. To solve the problem, I had to block access to the get and set simultaneously:

// ...snip

for (int i = 0; i < 10; i++)
    _sum = 0;
    Parallel.For(0, values.Length, (int value) =>
            lock (LockObject)
                _sum += value;
    System.Console.WriteLine("{0}/{1}", expectedSum, _sum);

This works as expected (I later updated it to use Interlocked.Add()). But if you look closely, it seems to destroy the concurrency! The point of the code is to sum an array of values, but if each thread can only execute serially there’s no value to having threads. What gives?

I didn’t believe summation is impossible to parallelize because addition is commutative. However, since adding a value to the sum must be atomic, I feel like it might not be something that can be done in parallel. When I remove the Sleep() call, this approach is faster than a single-threaded approach but much slower than some other approaches I took using the thread pool; those let each thread tally its own sum then added each thread’s individual sum at the end. I wish I could think of a way to do that elegantly with Parallel.For().

With the Sleep() calls inserted, Parallel.For() is dramatically faster than any of the other approaches I tried; I assume this is because the Sleep() calls don’t block concurrent access and the TPL might be shuffling tasks out if they’re idle. While the Sleep() call may seem useless, it could represent 10ms worth of work that I have to do once I’ve updated _sum; if I cache any values needed in the lock statement I could still gain some benefit from working with the cached values outside of the lock statement.

So if you’re using Parallel.For(), be mindful of whether any variables you touch are safe for concurrent access. If they aren’t, consider different approaches.

I guess I have to weigh in on Silverlight

I’m going to assume you’re familiar with the Microsoft stack and moderately familiar with the current furor over the shift in Silverlight’s strategy. If you’re not, this is going to be a boring post and you should move on.

I see a few camps right now. There are people heavily invested in SL that feel a bit upset. There are some people heavily invested in SL that feel this is a misunderstanding. There are some people that state the writing on the wall’s always been there. Let’s focus on the last people, because they have the only position that isn’t summarized by its description.

Silverlight was interpreted as many things at release; I’ve always felt like it was supposed to be a Flash competitor. Regardless, the message has been that Silverlight was there to fill in some gaps that standard HTML didn’t fill well. Indeed, there’s some things it still does that HTML 5 and its related technologies don’t address well. Microsoft’s new opinion is that Silverlight was never intended to take the place of simple HTML 5 applications, and instead was only intended for web applications that required a level of integration with the system that could not be achieved with HTML, even the superhero HTML 5. The more I think about it, the more I can’t understand why I didn’t see this message shine through from the beginning. Perhaps it’s the fault of their evangelism of SL for all things web, but that’s a different discussion.

The thing I don’t like about the “Silverlight is rightfully being snubbed in favor of HTML 5” arguments is many proponents ignore the fact that Silverlight is still a good option for those applications that need tight integration with the system. Too many arguments chastize developers for picking SL in the first place. Too many arguments celebrate the passing of SL (which isn’t dead yet) and can’t wait for the world in which they build their awesome HTML 5 applications. Let’s talk about the SL application I’m heavily invested in.

I have a hand in a part of LabVIEW Web UI Builder. LabVIEW is a graphical dataflow programming language primarily targeted at engineers. It has excellent support for analysis of large data sets, superb interoperability with many types of hardware, and implemented intuitive support for multicore parallelism before the MS stack even realized it was something worth working on. The Web UI Builder is an implementation of the programming language in Silverlight with stripped-down support; it’s not intended to replace LV but it’s going to be very handy for some remote configuration scenarios that are tricky to handle with plain old native code. You can put a web browser on pretty much anything, and since SL’s client-side that device can serve SL content without requiring much in the way of muscle. It’s a great fit.

I see no way this could have been implemented in HTML, CSS, and JS. We require the ability to let the user create a UI, use those UI elements to create a diagram that represents program code, compile that code into something, and run that. It’s nice to have access to the user’s hard drive for this stuff. In the ideal case, it’d be nice to be able to work with hardware connected to the system. Last I checked, that’s not really on anyone’s roadmap for HTML and related technologies. While this is the case, there will always be room for Silverlight.

Will Microsoft toss aside Silverlight like they did VB6 when .NET released? I’m not sure. The initial statement gave that impression, and the clarification seemed to skirt around the issue. I’d like to think it’s all an issue of poor planning on the part of MS. It’s possible that their statements seem (to an insider) that the question of continued Silverlight support is answered. Unfortunately, they’re preaching to a crowd that’s seen numerous well-accepted technologies pushed aside to make room for the latest. I don’t know that the murmurs are going to die down until details about SL 5 start to slip. April’s quite a long way to go. I think most of the discussion would die down if MS made it immediately clear that WP7 and the shift to HTML 5 isn’t going to take resources away from developing Silverlight as an excellent no-brainer deployment for cross-platform applications that need system integration. Right now Java and Mono are the only real story for that, and neither puts money in Microsoft’s pocket.

I’m writing SL code so long as my managers feel it’s the right tool for the job. I’m not an independent developer able to change stacks on a whim, and I don’t like that most of the community seems to ignore those of us that have roots and can’t switch jobs on a whim. I’m aware of the excellent work going on in the non-Microsoft world and I like to keep an eye on Ruby, Python, and a handful of other languages just in case. But I’m happy with my job, I like the people I work with, and I don’t have any problems with the Microsoft stack that are specific to Microsoft. I don’t aim to fix things that aren’t broken.

Is parameterized logic always harmful?

I’ve read plenty of times that parameterized logic is considered harmful in testable design.  What’s parameterized logic?  It’s stuff like this:

int Calculate(int lhs, int rhs, Operation op)
    if (Operation == Operation.Add)
        return lhs + rhs;
    else if (Operation == Operation.Subtract)

From what I understand, testable design would say this method needs to be refactored.  It does multiple things, and the op parameter dictates what happens.   The reason it’s discouraged is you end up encoding contract for *all* of the operations.  For example, if there is an Operation.Divide then the method will throw an exception if rhs is 0.  Testing this method is possible, but will be tedious.  Documenting this method will be a pain as well.

One alternative would be to replace the single Calculate() method with individual methods like Add(), Subtract(), and so on.  Another technique would involve creating an interface for a type that can operate on two numbers and letting Calculate() take one of those:

int Calculate(int lhs, int rhs, Operator op)
    return op.Operate(lhs, rhs);

Obviously the injection technique is more complicated, but it provides flexibility: in a library it allows the ability for users to provide their own implementations of Operator that perform operations that might not be built in.  Calculate() still has multiple behaviors, but the testing and documentation burden is shifted to the Operation implementations.

So what got me thinking about this?  Someone asked me how to convert to and from hexadecimal strings in .NET.  I realized there’s three ways to do it: Parse(), TryParse(), and Convert class methods.  I don’t like the thought of convincing someone there’s “one true way” to do things, so I outlined all three and noticed that all three techniques use parameterized logic.

The Parse() and TryParse() techniques will parse a number differently depending on the NumberStyles parameter you pass.  For example, “10” will parse as 10 unless NumberStyles.HexNumber is specified; then it will parse as 16.  Likewise, “B000” is a valid input only when the hex number style is specified.  From a testability standpoint, this seems like it’d require a matrix of tests for just the method.  From a documentation standpoint, Microsoft just documents that a FormatException can be thrown without going into any detail (granted, it’s usually easy to figure out why the exception was thrown.)

I feel like Convert’s methods do things differently.  The relevant methods take the string and an integer that represents the base for conversion.  This still introduces the problem that sometimes 10 means 16 and sometimes “A” is invalid.

So what’s different between the two?  From a user’s standpoint, not much.  If you try to guess the implementation, I bet they’re very different.  Byte.Parse() probably looks like this:

static byte Parse(string input, NumberStyles numberStyles)
    if (IsSet(numberStyles, numberStyles.HexNumber))
        // parse hexadecimal
        // parse decimal

    // validate the number using the various other styles

Convert.ToByte() could probably look like this:

static byte ToByte(string input, int base)
    // some algorithm that parses a number with an arbitrary base

I could use Reflector and peek at them, but I’m only using these as examples of the implementation styles I’m interested in (and yes, I know ToByte() only accepts 3 bases.)  I feel like ToByte() here is the lesser of two evils because of the internals.  Parse() has rigid rules that require you to walk through each possible path of the code if you want to create a 100% coverage of the logic.  ToByte() implements an algorithm that should work for many values of base, and thus you can write a smaller number of tests to get full logic coverage.

So I feel like depending on how you implement the parameterized logic, you might reduce the testing and documentation burden.  The Parse() implementation requires a suite of tests for every base and many combinations of the NumberStyles parameter.  The ToByte() implementation requires a suite of tests against an algorithm that takes a parameter.  It feels like that ought to reduce the number of tests; I can imagine using Xunit .NET’s theory tests to dramatically reduce the testing effort.

But I don’t think it’s so straightforward as, “Don’t use parameterized logic unless the parameter is an input to an algorithm.”  Consider what the interface for parsing numeric strings would look like if parameterized logic weren’t available:

structure Int32
    // ...

    static Int32 ParseHexNumber(...);
    static Int32 ParseHexNumberAllowWhitespace(...);
    static Int32 ParseHexNumberAllowLeadingWhitespace(...);
    static Int32 ParseHexNumberAllowTrailingWhitespace(...);
    static Int32 ParseHexNumberAllowWhitespace(...);

What a mess! I would not call this an improvement, even if it meant the testing/documentation were more clear.  So it looks like parameterized logic is yet another place where the developer must balance ease of use vs. maintainability.  While the pattern used in my Parse() implementation above is definitely a testing and maintenance nightmare, it is not acceptable to force the user to experience pain.

MSDN Redesign Number Ten Million

Microsoft has updated MSDN again for what feels like the third or fourth time in a couple of years.  Microsoft is really concerned with making sure it’s easy for new developers to pick up .NET, but I don’t think this redesign does it.

I think they missed the mark for true beginners.  I’ve never met anyone that started coding by saying, “I think I’d like to learn fundamentals of a programming language, then fundamentals of a GUI, then read a few dozen HOWTO articles that don’t have a lot to do with real applications.”  Instead, we start by saying something like, “I want to make my own Minesweeper” or “I want to make a Pac-Man clone”.  This redesign falls flat for this user.

The “desktop” page does a good job right up to step 4, the introduction videos.  “Build your first desktop RIA application with Silverlight?”  Why not just say “Build a smurfing smurf smurfer using SMURF?”  I think the video titles focus too much on what tools are used and not enough on getting the developer excited about what he’ll be doing.  Better titles would be “Build a desktop Twitter client with WPF” and “Build a browser or desktop Twitter client with Silverlight”.  When I was new, I’d expect a “my first application” tutorial to be simple.  If I saw a 30 minute “build your first application with WPF” I’d assume that WPF made it really complicated to build simple things.  If instead I saw “Build a Twitter client with WPF” I’d have understood that the video probably used some advanced features that needed explanation.  (On a side note; why on Earth is the thumbnail for the Silverlight code that sets up a WNDCLASSEX?)

Step 5 falls flat by showing a disorganized bullet list of links that are randomly bolded.  Section headers would be nice, but it’d work if similar concepts were grouped together.  Why is the MS Office developer center there?  Why is there a link to the VB developer center but not the C# developer center?  I’m not really sure what Microsoft was going for with these links.

When I first started, I thought MSDN was the appropriate resource to learn about writing Windows Forms applications from scratch.  This just isn’t the case.  MSDN is written in a technical tone and many of the articles assume at least a moderate familiarity with .NET.  There’s articles that help new developers, but they’re buried very deep in the Library hierarchy.  The “Getting Started with Windows Forms” page is exactly what I needed as a newbie who needed to write a WinForms application in a month.  Getting there is simple:

  1. Go to
  2. Click “Library”
  3. Click “.NET Development”
  4. Click “.NET 4”
  5. Click “Windows Forms Portal”
  6. Click “Getting Started With Windows Forms” (It doesn’t show up in the sidebar like on all of the other pages!)

If I go through the chain that leads me through it’s just as bad.  I get 3 links to help with Windows Forms: blogs (which are 99% about WPF), a guided tour of WPF (WTF?), and a videos page.  The videos page leads with “How Do I: SqlAzureLOB Line of Business” (mandatory “ATM machine” or perhaps “WPF Windows Presentation Foundation GUI Graphical User Interface” joke).  Is that what Microsoft’s research has indicated helps new programmers understand how to write applications?

I understand that WinForms is supposedly on its way out.  I haven’t noticed a decrease in students using it on the forums I frequent.  I gave the WPF links a whirl, and they’re in better shape, but the video page is useless to a newbie.  The first video on the page is “Create WPF Master-Detail UI Using Data Sources Window Object DataSource”.  I’ve used WPF for nearly 2 years now and I don’t know what “Data Sources Window Object DataSource” is supposed to mean.  Why isn’t MS leading with “Creating a Standard WPF Application” and listing the videos in increasing difficulty order?  Why isn’t there a “difficulty” or “intended audience” field that can sort the videos?

What I would change

The MSDN Library is most useful for a professional developer, but I feel like newbies should be made aware of the documentation.  The “How Do I” videos look nice, but they run the gamut from beginner to advanced with no indication as to their level.  They should have a level and they should be sortable by this level.  Users should be allowed to rate them and comment on them as well so newbies can be warned when someone labels “Write a SharePoint application using AzureCloudSqlSharePointLOBPOSWCF and ham" as a beginner video.

MSDN should really promote their forums as well.  I learned at least 80% of my WinForms knowledge from forums.  As part of promoting the forums, MSDN should also clean up the forums; my suggestions for that could easily fill another post.  The summary: you don’t need to dazzle newbies with over 100 different forums.  Make a “Basic .NET development” page with five forums: WinForms, WPF, Silverlight, Native, and ASP .NET.  Don’t make newbies have to decide if their question should go in “C# general”, “VS 2010 Development”, “WPF Development” or “.NET 4 WPF Beta Discussion”!

I think Microsoft should find a way to promote their blogs better as well.  It’d be nice if they kept an archive of the good blog articles rather than using an RSS feed of the most recent ones.  Pete Brown’s blog is chock full of great Silverlight tips ranging from beginner to advanced, but you wouldn’t know this from browsing MSDN.

A redesign won’t solve these problems.  Video in and of itself is not a solution to the problems that need to be addressed.  If Microsoft wants to help newbies, they need to buckle down and put some effort into designing an intuitive and accessible experience.  Right now the only reason I can find anything at all is my 8 years of experience with wrestling MSDN.

I Joined a Project for Fun

User ident on the XVBT forums asked for some comments and suggestions about his project.  I took a look at it and decided the number of comments sans explanation of fixes would exceed the size of a post, so I asked if I could join the project and make some lessons out of refactoring it.

The project itself is a neat little tool for automating ImageShack uploads.  On the outside, it looks pretty slick.  After inspecting the code, I have a bad feeling that it doesn’t work anywhere near as slick as it looks, but that’s why I’m here.  The application is an almost perfect example of what WinForms development does to suppress good software design practices.  In this ~3,000 line application, 2,600 of the lines are in ClientForm, the main form of the application.  This form is responsible not only for UI interaction, but all of the application logic.  There’s many other errors that are more related to what happens when a novice writes a large application than what WinForms inflicts upon you: dozens of unused methods, huge areas of commented-out code, no consistent naming conventions, etc. There’s at least a wrapper for the ImageShack API, but I haven’t peeked inside of that yet to see if it needs some work as well.  It looks like it was lifted from a blog by a man named Bryce Thomas, then converted from C# to VB.  I’m not sure if any attribution is currently given; if not I’m going to fix that.

The code for the client itself is not under any particular license, but does happen to have this notice at the top of each file:

' DX Coders
' Copyright 2001-2009 Simple Coders
' All Rights Reserved 
' Created: 09/06/09                                   *
' Author: Johnson

' NOTICE:  DX permits you to use, modify, and 
' distribute this file in any way.   
' DX takes no responsibility on how you use 
' this code. It is strictly for learning purposes
' and is not designed to cause harm. If you decide
' to reuse this code please give credit where credit is due.

I have entertained the notion that the developer(s) (there is a mysterious second developer involved that I’ve never met) are planning to have me clean up their application for free, then cut off my access to the project and sell it.  I would be disappointed if this happens, but I decided that the experience of reworking an application from a mess into something polished is something I need more than defense against my hobby work benefiting someone else.  The comments above mean that, should they excommunicate me from the project I have no qualms about releasing the source code and promoting the project as a fork under a very permissive copyleft license.

I have one concern at this point.  The code looks like it’s either a mishmash of examples gathered from various forums or the result of running a C# to VB .NET converter on a pre-existing project.  Indeed, one of the more questionable bits of code is admitted to be the result of running a converter on some C# example code.  If you have written an ImageShack upload client and this one looks familiar, please contact me with proof.  I will not work on a project that was ripped off.

As I work on refactoring, I’m going to make posts that detail why I did what I did.  I’m going to cross-post these onto the blog.  I’d normally do them *only* on the blog, but I don’t want to undermine XVBT’s policies by taking discussion of a user problem offsite.  I’m already skirting the edge by taking on a full project.

UI Control Naming Conventions

Microsoft was kind enough to publish a set of design guidelines for developing class libraries, and I use the book Framework Design Guidelines that is based on them daily. This has settled many disputes over the conventions our team should follow, and it’s the basis of many suggestions I make on the XVBT forums. The guidelines help lay out the practices that the .NET Framework team tries to adhere to when designing types. If everyone adheres to the guidelines, then the entirety of the .NET ecosystem will be consistent and usability will increase.

The guidelines have an odd position in the documentation. I find that most of MSDN and Microsoft’s other efforts are focused on helping the application developer. Contrary to this position, the design guidelines are focused on developers of class libraries that will be used by other developers. This is what I do, so it’s great for my demographic to get some love. However, the lack of focus on application development means there’s some important guidelines that aren’t there.

Chapter 3 of the books involves naming guidelines; you can follow along sans commentary online. The chapter discusses capitalization conventions and how to name every aspect of your code from variables to interfaces to DLLs. One omission that would be useful for application developers is guidelines for naming controls in applications.  I’ve experimented with 3 approaches, and each has its disadvantages.

1. Hungarian Notation

If this is established as the guideline, Hungarian notation is used for each control. That is, a text box for name input becomes txtName and a list view for displaying songs becomes lvSongs. Optionally, a leading underscore might be used, but I tend away from it when using this convention.

One benefit of this notation is familiarity. VB6 developers in particular favor this approach because it follows the generally agreed-upon conventions used in that language.  Another benefit is an increase in understandability.  When you see txtName, it is clear that this is a text box that represents a name.

One drawback is the naming guidelines use a strong DO NOT guideline to condemn Hungarian notation.  Nothing else in .NET uses Hungarian notation. This makes applications that follow the notation seem like they stick out a little. Another drawback is the notations aren’t really standardized. Most people agree on txt for TextBox and lv for ListView because these controls have been around forever, but newer controls like TableLayoutPanel and Grid don’t have agreed-upon prefixes. Also, how do you decide what to use for custom controls, UserControls, and third-party controls? One more drawback is this notation makes code brittle to change. Maybe your prototype starts with a TextBox but later you switch it to a NumericUpDown. This means you not only have to change the control and any logic that worked with it, but you also have to hunt down all references to the variable and rename it. (I admit I’m a relative newbie to Presentation Model patterns and it could be that this is less of a concern in those since the form would likely expose the control as a typed property, but I think it’s still applicable.)

To me, the drawbacks seem to outweigh the benefits. However, this is the convention I learned when I started in VB .NET many years ago, so I find it most comfortable and no matter how many arguments against it I hear, it’s the one I use.

2. Suffixes

When following this guideline, you pick a descriptive name and suffix it with the type of control. Use of camelCase or PascalCase is disputed, but generally I see PascalCase used more prominently with this technique. Using the examples from above, we’d use NameTextBox and SongsListView.

This has practically the same benefits and drawbacks as Hungarian Notation. You’re still identifying the type of control alongside the purpose, and it’s still clear from the variable name what kind of control is at work. This is technically a form of Hungarian notation, so still falls afoul of the DO NOT guideline. The problem with standardized prefixes is eliminated: since you use the full type name there’s no need for agreement. This technique is still brittle if you change controls.

Personally, I find that this convention clashes with how I think about the UI and makes it harder for me to find the variable, but this is probably because I’ve used Hungarian notation for years. I’ve tried following this guideline, but I find that more often than not I forget if I chose ItemCount or NumberOfItems as the prefix, and knowing the suffix doesn’t help me find it. Perhaps my naming discipline is poor, but it just doesn’t work for me.

3. Plain Old Variable Names

When following this guideline, you pick a descriptive name for the control and use that. There’s dispute over casing and usage of a leading underscore, but I find that two camps are the most prominent: PascalCase and _camelCase. Using our example controls, we would use Name and Songs or _name and _songs.

There are a few benefits to this approach.  One benefit is you aren’t using Hungarian notation so you aren’t falling afoul of any DO NOT guidelines. Another benefit is the code is no longer brittle if you change the control type.

Despite the benefits, there are many drawbacks to this approach no matter what casing convention is followed. If we’re writing a custom control or a custom UserControl that needs a text box for a name, then Name is already taken by Control.Name and we’ll have to pick a different name like PersonName. This can lead to accidental use of Name when you meant PersonName, and since you aren’t using the first name that came to mind you’re going to spend a lot of time trying to remember what your 2nd choice was. In addition, this casing convention is used for properties and constants, so if you have many of those your controls will be buried among them in Intellisense. This is why many people use the _camelCase convention, but since this is a very common convention for private fields it’s not much better.  Is _songs the control that represents the songs or a collection of songs? If you’ve got 20 properties with backing fields and 5 controls on the form, you have to wade through 25 entries if you can’t quite remember the correct name. _camelCase also looks particularly heinous when used as the x:Name attribute in XAML.

I find I am always dissatisfied when I use this convention.  If I use PascalCase then I almost always get the controls mixed up with constants. Even more often, the control name clashes with a property that I want to have and I end up having to pick a worse name for the control.  Then, I can’t remember the name I picked.  If I use _camelCase then the controls are buried among property backing fields, and name clashes still happen.  If _songs is the control that represents a list of songs and I want a Songs property, what do I do for the backing field? (There’s a few answers that involve generating the property value in different places, but most of them wouldn’t occur to a novice.) No matter how I try to follow this convention, I don’t like it.

I’m sure there’s other approaches I haven’t thought of, but these are the three I’ve tried. All of them have drawbacks that seem to outweigh the benefits, but I side with Hungarian notation out of familiarity. If there were guidelines to follow, I’d settle on the method they suggest, but there are none so I have a hard time deciding if I’m right.  What do *you* do?

Using a TextBox as an Adorner

I was fooling around with an adorner in a test project and decided to use a TextBox instead of a ComboBox for convenience.  Unfortunately, I found I couldn’t type into the TextBox.  According to Jim Nakashima, this can be addressed by setting the AdornerPanel.IsContentFocusable property, and he’s right.

I am bothered by the “bug” that sends “Delete” input to the designer instead of the TextBox.  I don’t call this a bug, I call it a showstopper.  Oh well, I guess I’ll be able to use TextBox controls in my adorners when we are able to drop VS 2008 support in 5 or 6 years.

Inheriting from ReadOnlyObservableCollection<T> and a Lesson about Constructors

I had need of returning a bindable collection from one of my classes, but didn’t want to allow the caller to modify the collection.  This generally requires a straightforward pattern in .NET: make a SomethingCollection class that derives from Collection<T> and a ReadOnlySomethingCollection class that derives from ReadOnlyCollection<T>, then only return the read-only version.  Most examples don’t bother with declaring the derived types, but I feel like it makes everything look better and the framework classes seem to favor declaring their own collection types as well.

I was having one heck of a time getting everything to work. I tried the most basic implementation:

public class ReadOnlySomethingCollection : ReadOnlyObservableCollection

This failed miserably with a fairly archaic error message:

‘full typename’ does not contain a constructor that takes ‘0’ arguments

I struggled with this for a while. The error message was clearly correct; if you walk the inheritance tree there’s no base class that defines a parameterless constructor. Still, defining a constructor that matched the signature of the 1-parameter constructor didn’t seem to be solving the problem. I decided it’d be best to step outside my project and make a simple example project in preparation for asking forums and newsgroups what was going on. It turns out switching languages to VB .NET was a good idea, too, because its error message was much more helpful once I had the constructor in place:

First statement of this ‘Sub New’ must be a call to ‘MyBase.New’ or ‘MyClass.New’ becasue base class ‘…’ does not have an accessible ‘Sub New’ that can be called with no arguments.

I saw this, thought about it for a minute, then had a forehead-slap moment. When a class derives from another, it’s almost as if you have two objects glued together. The base class has to be initialized before the derived class can be initialized, because the derived class’s constructor must be able to assume its base members are in a good state. So, in my case, the compiler was trying to initialize a ReadOnlyObservableCollection<T>, but since there was no parameterless constructor it couldn’t. The solution was to do exactly what VB said: make sure I call some base-class constructor as my first action. I finally got it to work in C#:

public class ReadOnlySomethingCollection : ReadOnlyObservableCollection
    public ReadOnlySomethingCollection(ObservableCollection list) : base(list)

This isn’t the first time that it’s taken VB error messages for me to understand the solution to my problem; I wish there was more consistency between the error messages.

Programmatically Creating Windows File Associations

A user on the VB Development Forum I’ve visited for a few years asked a question about creating file associations.  I chuckled and assumed that a Google search would return a wealth of information about the subject.  I was wrong; by my fifth combination of search terms I had found one site that had the minimal steps to get it done, and it wasn’t even correct.  The rest of the results were happy to discuss using the File Types tab of the Folder Options dialog to accomplish the task; this is not programmatic and not what the user wanted.  I remembered having a heck of a time trying to figure out how to make an association for all files (so I could have a right-click->Edit with hex editor option) so I decided I’d write up what I know.  Shame on you, internet, for letting the information get buried.

To start off, my example is technically incorrect.  I’m working with HKCR, but apparently the content here is generated based off of HKCU\Software and HKLM\Software. I assume this is so you can have per-user and global associations; I wrote my example using HKCR directly but you should probably use one of these two; please understand when I say HKCR I mean one of the other two locations.

I found the File Associations documentation, but haven’t had time to look over it properly.  For now, this should do.  In order to make it so that when you double-click a file your application opens you need three things:

  1. Your application should support opening a file from the command-line in some way.
  2. You need a registry key to associate a file type with the extension.
  3. You need a registry key to associate a program with the file type.

The first one is up to you; I can’t tell you how to do it.  The registry key to associate a file type with an extension is pretty easy.  File extensions are listed in HKCR under keys named after the extension (including the period!) The value of these keys is a string that defines the file type associated with the extension.  I tend to not use spaces in these, but I have no idea if spaces are unsupported; it will end up being the name of a subkey later and I’m too lazy to check if spaces are supported in subkey names.  For example, text files have the extension txt, and the key that specifies the file type is HKCR\.txt.  It’s default value is txtfile.

Now that there’s a file type associated with the extension, you need a registry key that tells the shell how to handle operations on the file type.  There’s lots of things to implement here, but I only know the basics.  File types are declared in subkeys of HKCR named after the file type; their subkeys and default values vary based on exactly how the file type is to be handled.  All I’m going to discuss is handling the "open" verb, which is generally invoked by double-clicking a file in the shell.  To add support for this verb, a tree of subkeys need to be created under HKCR\filetype. Working with our Notepad example above, we see HKCR\txtfile\shell\open\command.  It has a value that represents the path to Notepad and the replacement string %1 for the file that was selected.

Example time

Suppose we want to associate Notepad with the file extension .zzz.  We’ll start by defining a key for the file type:


Now, we create the file type key and associate the "Open" verb with notepad:

Value="%SystemRoot%\system32\NOTEPAD.EXE %1"

Note that though there are no quotes in the value for the open key, I’ve had trouble in the past when this string didn’t have anything that could possibly contain a space quoted. For example, I’m used to using:
"C:\Program Files\My Program\program.exe" "%1"
I’m not sure why Notepad’s special and doesn’t require this.   That’s really all I have to say on this topic for now; I am still looking over the documentation.