Correctly sized icon bound to Canvas object

I need to follow a method that retrieves an object Canvas

from the Resource Dictionary using a named collection and a relative URI, and links Canvas

to MenuItem

Icon

. This code for getting vector graphics 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;
}

      

Linking to my MenuItem

-

<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 also tried

<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 that I am trying to set the height Canvas

to 16 x 16 directly and also by reverting to filling the size rectangle, but that doesn't work - it just results in a blank image. If I do not specify the specifications Height

and Width

, the resulting graphics are too large.

I also tried resizing 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 leads to the disappearance of the image.

How do I properly resize my object Canvas

to fit mine MenuItem

?


Edit ( Partial answer ):

I came across many posts, but none of them resolved all the problems I had in one post. Problems:

  • Do not receive images using vector graphics. [Solved]
  • Retrieving images, but not properly scaled. [Solved]
  • Getting images scaled and displayed, but only one at a time. [Solved]
  • Imaged is scaled and rendered for all required MenuItems, but is aware that top-level menu items have unwanted headroom. [ON GOING]

The way I solved everything but the last problem was 1. use the correct image source for the vector graphics, in which case I found that filling the rectangle did the job. 2. You can bind to the Icon object directly to get images, but there is no real way to scale them accordingly. 3. You can scale images with a rectangle by setting Width

and Height

and filling this with VisualBrush

, but this aligns the resource amongst MenuItems

so only one will be displayed. To get Icons to be unseparated, you need to create a static resource and install 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

Now I have a problem where top-level items are also offset to the right (shown by the red arrow below) because the dimensions of the rectangle are hardcoded to 16. However, snapping to Witdh

and Height

seems to make the image disappear again ...

Layout Problem

Now I will try to create a menu item template and set the icon area to auto-fail. Any other solutions are appreciated ...

+1


source to share


2 answers


The two main problems were that the icons are split when not contained in an external static container (see edit question). The way I got it all to work in the end is using the following XAML:

<Rectangle x:Key="MenuItemIcon" x:Shared="False" 
           Visibility="{Binding IconVisibility}"
           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>

      



If the Visibility

default is MainMenuIcon

set to Visibility.Collapsed

. This provides the following kind of menu ...

Look

+1


source


Viewbox

can easily take care of such things by scaling the content to an accessible size

de-size the image and place the image inside the viewport

Example

<Setter Property="Icon">
    <Setter.Value>
        <Viewbox>
            <Image Source="{Binding IconSource}" />
        </Viewbox>
    </Setter.Value>
</Setter>

      

if you want to limit the size available, maybe you can apply the size in the viewport



eg,

<Viewbox Width="16" Height="16">

      

from MSDN: viewport

A Viewbox defines a content decorator that can stretch and scale a single child to fill the available space.

+1


source







All Articles