I have to following method that retrieves Canvas
object from a Resource Dictionary using the named assembly and a relative URI and binds the Canvas
to a MenuItem
s Icon
. This code to get the vector graphic Canvas
is
public Canvas GetVectorGraphic(string assemblyName, string relativeUri, string name)
{
var imageResourceDictionary = new ResourceDictionary();
imageResourceDictionary.Source =
new Uri(assemblyName + ";component/" + relativeUri, UriKind.Relative)
?? new Uri(relativeUri, UriKind.Relative);
if (imageResourceDictionary.Source == null)
return default(Canvas);
return imageResourceDictionary[name] as Canvas;
}
The binding to my MenuItem
is
<Style x:Key="MenuItem" TargetType="{x:Type Controls:MenuItemEx}">
<Setter Property="Icon">
<Setter.Value>
<Image Source="{Binding IconSource}" Width="16" Height="16"/>
</Setter.Value>
</Setter>
...
I have also attempted
<Setter Property="Icon">
<Setter.Value>
<Rectangle Width="16" Height="16">
<Rectangle.Fill>
<VisualBrush Stretch="Uniform"
Visual="{Binding IconSource}"/>
</Rectangle.Fill>
</Rectangle>
</Setter.Value>
</Setter>
You can see I am both attempting to set the height on the Canvas
to 16 x 16 directly and also by reverting to fill a sized rectangle, but this is failing - it just results in a blank image. If I leave out the Height
and Width
specifications the resulting graphic is too large.
I have also attempted to resize the Canvas
when I read it from the dictionary via
...
Canvas c = imageResourceDictionary[name] as Canvas;
c.Height = 16;
c.Width = 16;
return c;
But this causes the image to disappear.
How can I correctly re-size my Canvas
object to fit my MenuItem
?
Edit (Partial Answer):
I have come accross many many posts, but none that solved all the issues I was having in one post. The problems:
- Not getting any images displayed using vector graphics. [SOLVED]
- Getting images displayed but not correctly scaled. [SOLVED]
- Getting images scaled and displayed but only one at a time. [SOLVED]
- Imaged are scaled and displayed for all required MenuItems but know the top level menu items have an unwanted margin. [ON GOING]
How I solved all but the last issue was 1. use the correct image source for vector graphics, in this case i found that filling a rectangle did the job. 2. You can bind to the Icon object directly to get the images, but there is no real way of scaling these appropriately. 3. You can scale the images by using a rectangle, setting Width
and Height
and filling this with a VisualBrush
, but this shars the resource among MenuItems
so only one will ever show up. To get the Icons to be non-shared you have to create a static resource and set x:Shared="False"
. The final XAML looks like
<Rectangle x:Key="MenuItemIcon" x:Shared="False"
HorizontalAlignment="Stretch" VerticalAlignment="Stretch"
Width="16" Height="16">
<Rectangle.Fill>
<VisualBrush Stretch="Uniform" Visual="{Binding IconSource}"/>
</Rectangle.Fill>
</Rectangle>
<Style x:Key="MenuItem" TargetType="{x:Type Controls:MenuItemEx}">
<Setter Property="Icon" Value="{StaticResource MenuItemIcon}"/>
<Setter Property="InputGestureText" Value="{Binding InputGestureText}"/>
<Setter Property="Caliburn:Action.Target" Value="{Binding}"/>
<Setter Property="Caliburn:Message.Attach" Value="{Binding ActionText}"/>
</Style>
Outstanding Problem
I now have the issue where the top level items are also shifted to the right (shown with red-arrow below) because the rectangle dimensions are hard coded to 16. However, binding to the Witdh
and Height
seems to cause the image to disappear again...
I am now going to attempt to template the menu item and set the Icon area to auto-collapse. Any other solutions are welcome...