Assigning adorners with dynamically created controls

I was trying to add an adorner to the WPF TextBox to add a cue banner.  I was creating the controls at runtime and I am relatively clueless with WPF.  I wanted my text boxes to show a grayed out text prompt in the edit fields when they are empty.  In HTML5, that would be the placeholder attribute.  In Win32, it’s called a cue banner.

While Win32 (since XP) supports the cue banner for text input controls (single line input only, everybody else can go away), WPF has no built-in support for the cue banner.  There are a few ways to add this behavior.  I read one suggestion that described how to a style to the control, with triggers to handle the showing and hiding of the cue banner.

That looked a little messy to me and would be specific to a single type of control.  I found an article by Jason Kemp that described how to implement a cue banner as an adorner to the control.  He provides a service class with a static  method to assign a cue banner object to a control.  That object could be a string, an image, a form, it doesn’t matter.  That method wraps up the code to assign an adorner to the destination object.

I was adding TextBox contols to a grid using the following code

  var tb = new TextBox { Margin = new Thickness(8.0, 0.0, 4.0, 4.0) };

  tb.SetValue(Grid.ColumnProperty, 1);
  tb.SetValue(Grid.RowProperty, i);

  grid.Children.Add(tb);
  CueBannerService.SetCueBanner(tb, SomeCueValue);

The call to SetCueBanner was throwing an exception trying to add the adorner to the control. To add an adorner in code you follow the following pattern:

  AdornerLayer layer = AdornerLayer.GetAdornerLayer(control);
  // code here for creating a new adorner
  layer.Add(newAdorner);

This code was blowing up because GetAdornerLayer was returning null.  Because I was building up the controls dynamically, I missing the AdornerLayer that GetAdornerLayer is trying to get a hold of.  The cue banner adorner needs an AdornerLayer to render the controls on to.

The solution was to create an instance of AdornerDecorator and assign the TextBox to it, then add the decorator to the grid in the same manner as I had added the TextBox

  var decorator = new AdornerDecorator();

  var tb = new TextBox { Margin = new Thickness(8.0, 0.0, 4.0, 4.0) };

  decorator.SetValue(Grid.ColumnProperty, 1);
  decorator.SetValue(Grid.RowProperty, i);

  decorator.Child = tb;

  grid.Children.Add(decorator);
  CueBannerService.SetCueBanner(tb, SomeCueValue);

Once I did that, everything fell into place.

Converting enums and Camel case text to words

I have enums that I want to display on a form and I wanted to make them look a little better on the screen.  The constants defined in the enumerator list are defined using Camel case.  Like “firstName” or  “mobileNumber”.  Most of the values could be displayed by converting the Camel cased string to words.

Using some bits and pieces from Stack Overflow, I wrote a string extension class to do the conversion.  The first thing it does is to convert the enum to a string, then force the first letter to uppcase case, then finally split the text into words, with each uppercase letter designating a new word.

public static class StringHelper
{
    public static string FirstCharToUpper(this string input)
    {
        if (String.IsNullOrEmpty(input))
            return input;

        return input.First().ToString().ToUpper() + String.Join("", input.Skip(1));
    }

    public static string CamelCaseToWords(this string input)
    {
        return Regex.Replace(input.FirstCharToUpper(), "([a-z](?=[A-Z])|[A-Z](?=[A-Z][a-z]))", "$1 ");
    }
}

I posted an example on DotNetFiddle, which is basically the C#/VB.Net/F# equivalent of JSFiddle, a great tool for quickly trying out some code.  The sharing feature is nice.  I can embed a runnable copy of code (as shown below) or I can work with another developer using their TogetherJS integration.

The cool thing about the sample code above is that you can edit it in-place and try some other values.  Replace “thisIsCamelCase” with “MooseAndSquirrel” and you should see the results immediately.

And then I stuck shipping tape on the back of the SIM card

I just did a simple hardware hack to my HTC 8X phone.  I have been having random problems where the phone loses it’s ability to make calls or to send SMS messages.  And it will do a spontaneous reboot every once in a while.  So I took the SIM card out and stuck some tape to the back of it and put it back in.

HTC 8XThese problems has been going on for months and a bunch of people have been complaining about it on the Microsoft and Verizon forums.  Some people have been reporting that the problem goes away if you change the settings, but that doesn’t appear to be the fix.  I think there are two problems, one hardware related with the SIM card tray, the other one a firmware issue.

The firmware problem appears to be related to what has been reported as an issue with SMS traffic and with which switch the phone is connected to at the time.  When this happens, I have to put the phone in “Airplane Mode” and then back to normal.  Usually, I get SMS functionality again after doing so.    Until Verizon and HTC decide to fix this, there’s nothing else I can do about that.  Short of a miracle in the 8.1, I’m not expecting any fixes on that.

The other problem is that the SIM card appears to lose it’s connection with the phone.  When that happens I lose voice and SMS and sometimes the phone reboots.  That I can try to fix.  A few people have reported fewer SMS and reboot issues after padding the SIM card with tape.  A couple of pieces of tape are enough to keep the SIM card in tighter contact with the phone.  So I took the card out and applied some tape, as seen in the following photo:

You can see the edges of the tape past the edges of the card.  It’s actually a MicroSIM card and it fits in a little tray that goes into the side of the phone.  You don’t need much tape.  I used clear shipping tape, just two pieces were enough.  The SIM card tray went in with a snug fit.  Hopefully my ability to send SMS messages will be a little more reliable.  I like this phone, but being able to make calls and send text messages should be the more reliable part of a phone.

How to use Bing Code Search when ReSharper is installed

Microsoft Research just released a cool add-in for Visual Studio 2013 called Bing Code Search.  It allows you to search for code samples from with the IDE and has enough context awareness to use the variables from your code.


If you have ReSharper installed, the two do not play together.  You need to trigger Intellisense to get Bing Code Search to activate. ReSharper overrides the Visual Studio Intellisense for it’s additional functionality.  That prevents Bing Code Search from working.

Hopefully Jetbrains will update ReSharper to work with Bing Code Search and hopefully Microsoft will provide an alternate means of triggering Bing Code Search just read the last paragraph of this post.  In the mean time, you can hack away around the problem by disabling ReSharper when you want to use Bing Code Search.

The easiest A clunky way I found to do that was to write a macro that calls the ReSharper toggle command and then bind that macro as a button on the standard tool bar.  Since originally posting this,  two comments left from JetBrains provide easier ways of doing this.

Install the Virtual Commander (or here) extension.  This tool will let you create commands and extensions.  After installing Virtual Commander and restarting Visual Studio, select “Commands…” from the VCMD menu.  In the Commands panel click the “Add” button.

This will open up the command editor window with a new command already scaffolded.  You just need to add the command that will toggle ReSharper on and off, ReSharper_ToggleSuspended.  The command should look something like this

Imports EnvDTE
Imports EnvDTE80

Public Class C
    Implements VisualCommanderExt.ICommand

    Sub Run(DTE As EnvDTE80.DTE2, package As Microsoft.VisualStudio.Shell.Package) Implements VisualCommanderExt.ICommand.Run
        DTE.ExecuteCommand("ReSharper_ToggleSuspended")
    End Sub
End Class

The text that you enter in the name field will be what shows up as the caption of the button on the tool bar. You can test the command by clicking on the Run button.  You should the Resharper menu disappear from the IDE.  Press Run again to bring it back,

After saving the command, you can add it to a toolbar. I placed it on the standard toolbar, so I would know where it was at all times.  Select Tools->Customize…, then click the Commands tab.  You can put this button anywhere, but I placed it on the Standard menu.  Click the Add Command… button.  Then scroll down the Categories list and click on VCmd.  Select the Command you had entered, if it’s the first one then it will be Command01.  Press the OK button to add the command as a toolbar button, then press Close to close the Customize dialog.

If all went well, you will have a new button on the tool bar, with the name of the command as it’s caption.  And now you can toggle ReSharper on and off at any time.

[Edit]
An easier alternative (thanks to Jura) would be to bind a shortcut key to the ReSharper command.  Another suggestion would be to bind a shortcut key to Tools.LaunchSnippetSearch (thanks to Matt) that would open snippet search pane.  Use Tools->Options->Keyboard to access the key bindings.

When the EditorPackage does not load correctly

I had this “The ‘Microsoft.VisualStudio.Editor.Implementation.EditorPackage’ package did not load correctly.” error message when I started up Visual Studio 2013.  My PC had rebooted earlier in the day as a result of some Windows Updates.  Now I was getting this error dialog:

The 'Microsoft.VisualStudio.Editor.Implementation.EditorPackage' package did not load correctly.

This is telling me to open ActivityLog.xml, and hopefully an answer will be found.  So I opened up that file and found some error entries

<entry>
 <record>541</record>
 <time>2014/02/16 02:00:07.011</time>
 <type>Error</type>
 <source>VisualStudio</source>
 <description>SetSite failed for package [Microsoft.VisualStudio.Editor.Implementation.EditorPackage]</description>
 <guid>{E269B994-EF71-4CE0-8BCD-581C217372E8}</guid>
 <hr>80070057 - E_INVALIDARG</hr>
 <errorinfo>No EditorOptionDefinition export found for the given option name: Graphics/Simple/Enable
Parameter name: optionId</errorinfo>
 </entry>

Something must have changed with the Windows updates and it was enough to cause an issue. This problem seems happens enough with various versions of Visual Studio that you can bingle it and get the same answer.  You need to clear the ComponentModelCache folder.  For Visual Studio 2013, it’s located in the %LOCALAPPDATA%\Microsoft\VisualStudio\12.0 folder.

I renamed ComponentModelCache to ComponentModelCache.Borked and restarted Visual Studio.  It started right up and without any errors.

Locating the right web.config file at runtime

I created a Web API web service that’s part of a shrink wrapped application. The service has a web.config that the end user will need to configure some settings in.  Editing a web.config manually is, at best, annoying.

Man Screaming

If your app requires manual XML editing, then you failed

I usually provide a desktop app for editing the web.config file.  I want the user to be able to point and click as much of the settings as possible. It’s also possible for this web service to be deployed as multiple instances on the same server, so I wanted to make easier for the user to configure the files.

I wrote a simple WPF app that would let the user edit a specific type of web.config  and that user could edit the settings and not have to worry about the syntax issues that come with the angle bracket tax.  I’m a firm believer in Steve Krug’s “Don’t make me think” philosophy. And editing XML is about as far away as you can get from that.

Instead of hard coding the path to the web.config file I made the config editor a little smarter and gave it the ability to locate all instances of the web.config that it knows how to edit.   I created a helper class with a few methods that would return a list of web.config files with the full path.  That list was bound to the dropdown list and the code would load the correct web.config when the selection changed.

The first step was to locate all of the web.config files.  In the Microsoft.Web.Administration namespace, we have the ServerManager class.  The ServerManager class is documented as “Provides read and write access to the IIS 7 configuration system.” .  That’s exactly what I need.

Take the following method;

public List GetWebApiFolders()
{
    List folders = new List();

    ServerManager iisManager = new ServerManager();

    foreach (var s in iisManager.Sites)
    {
        foreach (var app in s.Applications)
        {
            foreach (var dir in app.VirtualDirectories)
            {
                if (IsWebApiFolder(dir.PhysicalPath))
                {
                    if (!folders.Contains(dir.PhysicalPath))
                        folders.Add(dir.PhysicalPath);
                }
            }
        }
    }

    return folders;
}

We iterate through each site in the Sites collection. Then for all of the apps for each site. Then for all of the virtual directories for each app. I call a method called IsWebApiFolder() and pass in the physical path to that virtual directory.  The IsWebApiFolder() method will return true if this folder contains a web.config that my config editor can edit.

Let’s take a look at IsWebApiFolder()

private Boolean IsWebApiFolder(string folderName)
{
    Boolean result = File.Exists(
      Path.Combine(folderName, "SomeCustomHandler.ashx"));

    if (result)
    {
        XDocument doc = 
          XDocument.Load(
           Path.Combine(folderName, "web.config"));

        var node = doc.Descendants("appSettings")
          .Elements("add")
          .Where(n => n.Attribute("key")
          .Value == "Crazy.App");

        result = node.Count() > 0;
    }

    return result;
}

The first thing it does is to look for a file with an uncommon name.  It doesn’t matter which file you  pick, just make it fairly unique to your app.  It could even be an empty text file named “ThisIsTheFooBar.txt”.  After finding a folder that has what could be my app’s files, I parse the web.config and look for a specific setting.  If it has that setting, then I’m pretty confident that I have found the right file. When I find the right file, I return true back to the caller, which then adds that file to the list of web.config files that can be edited.

Screaming Man image By Crosa (Flickr: Scream) [CC-BY-2.0], via Wikimedia Commons