Databound menu item names in XAML

I keep telling the engineers who work with me that once we ship, we’ll have to write some articles with all the tips and tricks that we’ve discovered in Microsoft’s .NET Framework v.3, specifically WPF and WCF. The technology is easy enough to use, as I’ve written before, that even a product manager can do it.

My engineers challenged me to find a way to dynamically bind the name of our application into the menus, so that we would not have to update the menu names separately when we changed the code name of the product to the final released name. After some playing around, it turns out to be pretty trivial. As in my About Box example, you have to reference the AssemblyInfo class, which has the name of the assembly as a property that can be databound. Then it’s just a question of databinding the name to the menu.

With the way that menus are created by default in Expression Blend, this can look tricky because the text that is shown is in a parameter of the MenuItem tag called Header. What you have to remember is that WPF allows you to embed other controls into various contexts, but that you generally have to be explicit about how you’re doing it. So your code might have started out looking like this:

<MenuItem Header="_Help">
  <MenuItem Header="_About MyProgramName"/>
  <MenuItem Header="MyProgramName Help"/>
</MenuItem>

After you break out the header element and embed the databound names, it ends up looking like this:

<MenuItem Header="_Help">
  <MenuItem>
    <MenuItem.Header>
       <TextBlock>
          <TextBlock Text="About " />
          <TextBlock Text="{Binding Path=Info.Title, Mode=Default, Source={StaticResource ApplicationBaseDS}}" />
       </TextBlock>
    </MenuItem.Header>
  </MenuItem>
  <MenuItem>
     <MenuItem.Header>
        <TextBlock>
           <TextBlock Text="{Binding Path=Info.Title, Mode=Default, Source={StaticResource ApplicationBaseDS}}" />
           <TextBlock Text=" Help" />
        </TextBlock>
     </MenuItem.Header>
  </MenuItem>
</MenuItem>

It’s probably obvious enough to an experienced WPF programmer, but I found no ready references for making this happen so I figured I’d give it back to Google.