Click here to Skip to main content
13,139,520 members (67,137 online)
Rate this:
Please Sign up or sign in to vote.
In a WPF client application, I'm having some difficulties using hierarchical data template to load databound menuitems.

First I created the ViewModel, containing the basic properties for a menu item : Title, Command, ImageSource (Path to the image to use for Icon property) and sub items.

Then, I created the view in a XAML window to display my menus. To bind my collection, taking sub items into account, I used the hierarchical data template for the menu item template.

Here is the XAML code for the ItemTemplate :

<HierarchicalDataTemplate DataType="{x:Type vm:MenuItemViewModel}" ItemsSource="{Binding Path=Items}">
        <Style TargetType="MenuItem">
                <Image x:Key="ItemImage" Source="{Binding ImageSource}" Width="16" Height="16" x:Shared="false" />
                <Setter Property="Command" Value="{Binding Command}" />
                <Setter Property="CommandParameter" Value="{Binding CommandParameter}" />
                <Setter Property="Icon" Value="{StaticResource ItemImage}" />
    <StackPanel Orientation="Horizontal">
        <TextBlock Text="{Binding Title}" />

When I initialize the menus and show the window, all looks fine.

After that, I tried to put the menu item template into a resource dictionary in order to be able to reuse it from wherever in my application as a default template.
When I do that, I have an exception thrown :
Shared attribute in namespace '' can be used only in compiled resource dictionaries.

After spending so much time searching for a solution, I finally made a tester project (available here) to demonstrate the problem.

I don't know how to make my resource dictionary being a compiled resource dictionary...
Could anyone help me ?
Posted 10-Sep-12 0:34am

1 solution

Rate this: bad
Please Sign up or sign in to vote.

Solution 1

Hi Peltchag,

I had the same problem and AFAIK this isn't possible for resource dictionaries.

What I ended up with is using a ValueConverter in my DataTemplate.

Make the converter accessible (where local is an alias for the namespace)
<local:menuiconconverter x:key="menuIconConverter" xmlns:x="#unknown" xmlns:local="#unknown" />

And then write in your DataTemplate something like:
<setter property="Icon" value="{Binding ImageSource, Converter={StaticResource menuIconConverter}}" />

And in the namespace referenced by local, this class:
   using System;
   using System.Globalization;
   using System.Windows.Controls;
   using System.Windows.Data;
   using System.Windows.Media.Imaging;
   [ValueConversion(typeof(String), typeof(Image))]
   public class MenuIconConverter : IValueConverter
      #region IValueConverter implementation
      public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
         if (value == null)
            return Binding.DoNothing;
         string imageUrl = value.ToString();
         if (string.IsNullOrEmpty(imageUrl))
            return Binding.DoNothing;
         var bmp = new BitmapImage(new Uri(imageUrl, UriKind.RelativeOrAbsolute)) { DecodePixelHeight = 16, DecodePixelWidth = 16 };
         return new Image { Width = 16, Height = 16, Source = bmp, UseLayoutRounding = true, SnapsToDevicePixels = true };
      public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
         return Binding.DoNothing;

Hope this helps,


Peltchag 10-Sep-12 8:28am
This solution work fine.
I was expecting not to write code behind to solve this, but if it's the only way... :)

Thanks for your help !
Thomas Duwe 10-Sep-12 8:40am
Yeah, I too was against code behind in this case, but I found no other way :-(

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

  Print Answers RSS
Top Experts
Last 24hrsThis month

Advertise | Privacy |
Web02 | 2.8.170915.1 | Last Updated 10 Sep 2012
Copyright © CodeProject, 1999-2017
All Rights Reserved. Terms of Service
Layout: fixed | fluid

CodeProject, 503-250 Ferrand Drive Toronto Ontario, M3C 3G8 Canada +1 416-849-8900 x 100