5

I'm populating a Ribbon (WPF) programmatically based on MS RibbonControlsLibrary (3.5.41019.1). All images (most noticeable large images) looks very bad and "pixly":

Screenshot from 2 Ribbon

  • The top screenshot is from the "pixly" Ribbon (Image scaling looking bad)
  • The bottom screenshot is taken from the same area in a window based on WinForms with the same source images (Image scaling looking good)
  • All images are saved in 32 bit PNG 48x48

I have tried to set the BitmapScalingMode to "HighQuality" without any effect, source code:

BitmapImage img = new BitmapImage();
try
{
    Uri uri = new Uri("pack://application:,,,/UIMainWindow;component/Resources/" + iPictureName);                
    img.BeginInit();
    img.SetValue(BitmapImage.CacheOptionProperty, BitmapCacheOption.OnLoad);
    RenderOptions.SetBitmapScalingMode(img, BitmapScalingMode.HighQuality);
    img.UriSource = uri;
    img.EndInit();
    img.Freeze();
}
catch (Exception ex)
{
    throw new Exception("Creation of image failed: " + ex.Message, ex);
}

Question Why is the scaling of the images looking bad? And how can I solve this?

sashkello
  • 17,306
  • 24
  • 81
  • 109
vanos
  • 99
  • 1
  • 6

4 Answers4

1

None of the other answers above worked for me so I started my own investigation. Resizing the images to 32x32 almost fixed the problem, but we have users with different DPI settings and the images wouldn't scale correctly on their machines. I should also note that I'm using the System.Windows.Controls.Ribbon assemly, which may behave a little differently than the RibbonControlsLibrary.

I found that the default ControlTemplate for the RibbonButton has specifically specified NearestNeighbor as the bitmap scaling option. The good news is that it's easy to override this control template by dropping a style into your Window's resources. The slightly bad news is that the control template is pretty verbose. I dumped the default ControlTemplate for the RibbonButton on my system to a file and just changed the bitmap scaling option.

First, you'll need this namespace declaration at the top of your file if you don't have it already:

xmlns:s="clr-namespace:System;assembly=mscorlib"

Then put this Style in your Window's resources in order to override the RibbonButton appearance:

<Style TargetType="RibbonButton">
    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="RibbonButton">
                <Border BorderThickness="{TemplateBinding Border.BorderThickness}" CornerRadius="{TemplateBinding RibbonControlService.CornerRadius}" BorderBrush="{TemplateBinding Border.BorderBrush}" Background="{TemplateBinding Panel.Background}" Name="OuterBorder" SnapsToDevicePixels="True">
                    <Border BorderThickness="{TemplateBinding Border.BorderThickness}" Padding="{TemplateBinding Control.Padding}" CornerRadius="{TemplateBinding RibbonControlService.CornerRadius}" BorderBrush="#00FFFFFF" Name="InnerBorder">
                        <StackPanel Name="StackPanel">
                            <Image Source="{TemplateBinding RibbonControlService.LargeImageSource}" Name="PART_Image" Width="32" Height="32" Margin="{DynamicResource {ComponentResourceKey TypeInTargetAssembly=Ribbon, ResourceId=LargeImageMargin}}" HorizontalAlignment="{TemplateBinding Control.HorizontalContentAlignment}" VerticalAlignment="Center" RenderOptions.BitmapScalingMode="HighQuality" />
                            <Grid Name="Grid" HorizontalAlignment="Center" VerticalAlignment="Center">
                                <RibbonTwoLineText TextAlignment="Center" LineHeight="13" LineStackingStrategy="BlockLineHeight" Text="{TemplateBinding RibbonControlService.Label}" Name="TwoLineText" Margin="1,1,1,0" HorizontalAlignment="Center" VerticalAlignment="Top" />
                            </Grid>
                        </StackPanel>
                    </Border>
                </Border>
                <ControlTemplate.Triggers>
                    <DataTrigger Binding="{Binding Path=ControlSizeDefinition.ImageSize, RelativeSource={RelativeSource Mode=Self}}" Value="Large">
                        <Setter Property="FrameworkElement.MinWidth">
                            <Setter.Value>
                                <s:Double>44</s:Double>
                            </Setter.Value>
                        </Setter>
                        <Setter Property="FrameworkElement.Height">
                            <Setter.Value>
                                <s:Double>66</s:Double>
                            </Setter.Value>
                        </Setter>
                        <Setter Property="FrameworkElement.MinHeight" TargetName="Grid">
                            <Setter.Value>
                                <s:Double>26</s:Double>
                            </Setter.Value>
                        </Setter>
                        <Setter Property="RibbonTwoLineText.HasTwoLines" TargetName="TwoLineText">
                            <Setter.Value>
                                <s:Boolean>True</s:Boolean>
                            </Setter.Value>
                        </Setter>
                    </DataTrigger>
                    <DataTrigger Binding="{Binding Path=ControlSizeDefinition.ImageSize, RelativeSource={RelativeSource Mode=Self}}" Value="Small">
                        <Setter Property="FrameworkElement.Height">
                            <Setter.Value>
                                <s:Double>22</s:Double>
                            </Setter.Value>
                        </Setter>
                        <Setter Property="FrameworkElement.Margin" TargetName="PART_Image">
                            <Setter.Value>
                                <Thickness>1,0,1,0</Thickness>
                            </Setter.Value>
                        </Setter>
                        <Setter Property="Image.Source" TargetName="PART_Image">
                            <Setter.Value>
                                <Binding Path="SmallImageSource" RelativeSource="{RelativeSource Mode=TemplatedParent}" />
                            </Setter.Value>
                        </Setter>
                        <Setter Property="FrameworkElement.Width" TargetName="PART_Image">
                            <Setter.Value>
                                <s:Double>16</s:Double>
                            </Setter.Value>
                        </Setter>
                        <Setter Property="FrameworkElement.Height" TargetName="PART_Image">
                            <Setter.Value>
                                <s:Double>16</s:Double>
                            </Setter.Value>
                        </Setter>
                        <Setter Property="FrameworkElement.HorizontalAlignment" TargetName="TwoLineText">
                            <Setter.Value>
                                <x:Static Member="HorizontalAlignment.Left" />
                            </Setter.Value>
                        </Setter>
                        <Setter Property="FrameworkElement.Margin" TargetName="TwoLineText">
                            <Setter.Value>
                                <Thickness>1,1,1,1</Thickness>
                            </Setter.Value>
                        </Setter>
                        <Setter Property="StackPanel.Orientation" TargetName="StackPanel">
                            <Setter.Value>
                                <x:Static Member="Orientation.Horizontal" />
                            </Setter.Value>
                        </Setter>
                    </DataTrigger>
                    <MultiDataTrigger>
                        <MultiDataTrigger.Conditions>
                            <Condition Binding="{Binding Path=ControlSizeDefinition.ImageSize, RelativeSource={RelativeSource Mode=Self}}" Value="Small" />
                            <Condition Binding="{Binding Path=IsInQuickAccessToolBar, RelativeSource={RelativeSource Mode=Self}}" Value="True" />
                        </MultiDataTrigger.Conditions>
                        <Setter Property="FrameworkElement.Height">
                            <Setter.Value>
                                <s:Double>NaN</s:Double>
                            </Setter.Value>
                        </Setter>
                    </MultiDataTrigger>
                    <DataTrigger Binding="{Binding Path=ControlSizeDefinition.IsLabelVisible, RelativeSource={RelativeSource Mode=Self}}" Value="False">
                        <Setter Property="UIElement.Visibility" TargetName="TwoLineText">
                            <Setter.Value>
                                <x:Static Member="Visibility.Collapsed" />
                            </Setter.Value>
                        </Setter>
                    </DataTrigger>
                    <DataTrigger Binding="{Binding Path=ControlSizeDefinition.ImageSize, RelativeSource={RelativeSource Mode=Self}}" Value="Collapsed">
                        <Setter Property="UIElement.Visibility" TargetName="PART_Image">
                            <Setter.Value>
                                <x:Static Member="Visibility.Collapsed" />
                            </Setter.Value>
                        </Setter>
                    </DataTrigger>
                    <Trigger Property="UIElement.IsMouseOver">
                        <Setter Property="Panel.Background" TargetName="OuterBorder">
                            <Setter.Value>
                                <Binding Path="MouseOverBackground" RelativeSource="{RelativeSource Mode=TemplatedParent}" />
                            </Setter.Value>
                        </Setter>
                        <Setter Property="Border.BorderBrush" TargetName="OuterBorder">
                            <Setter.Value>
                                <Binding Path="MouseOverBorderBrush" RelativeSource="{RelativeSource Mode=TemplatedParent}" />
                            </Setter.Value>
                        </Setter>
                        <Setter Property="Border.BorderBrush" TargetName="InnerBorder">
                            <Setter.Value>
                                <SolidColorBrush>#80FFFFFF</SolidColorBrush>
                            </Setter.Value>
                        </Setter>
                        <Trigger.Value>
                            <s:Boolean>True</s:Boolean>
                        </Trigger.Value>
                    </Trigger>
                    <Trigger Property="UIElement.IsKeyboardFocused">
                        <Setter Property="Panel.Background" TargetName="OuterBorder">
                            <Setter.Value>
                                <Binding Path="FocusedBackground" RelativeSource="{RelativeSource Mode=TemplatedParent}" />
                            </Setter.Value>
                        </Setter>
                        <Setter Property="Border.BorderBrush" TargetName="OuterBorder">
                            <Setter.Value>
                                <Binding Path="FocusedBorderBrush" RelativeSource="{RelativeSource Mode=TemplatedParent}" />
                            </Setter.Value>
                        </Setter>
                        <Setter Property="Border.BorderBrush" TargetName="InnerBorder">
                            <Setter.Value>
                                <SolidColorBrush>#80FFFFFF</SolidColorBrush>
                            </Setter.Value>
                        </Setter>
                        <Trigger.Value>
                            <s:Boolean>True</s:Boolean>
                        </Trigger.Value>
                    </Trigger>
                    <Trigger Property="ButtonBase.IsPressed">
                        <Setter Property="Panel.Background" TargetName="OuterBorder">
                            <Setter.Value>
                                <Binding Path="PressedBackground" RelativeSource="{RelativeSource Mode=TemplatedParent}" />
                            </Setter.Value>
                        </Setter>
                        <Setter Property="Border.BorderBrush" TargetName="OuterBorder">
                            <Setter.Value>
                                <Binding Path="PressedBorderBrush" RelativeSource="{RelativeSource Mode=TemplatedParent}" />
                            </Setter.Value>
                        </Setter>
                        <Setter Property="Border.BorderBrush" TargetName="InnerBorder">
                            <Setter.Value>
                                <SolidColorBrush>#00FFFFFF</SolidColorBrush>
                            </Setter.Value>
                        </Setter>
                        <Trigger.Value>
                            <s:Boolean>True</s:Boolean>
                        </Trigger.Value>
                    </Trigger>
                    <Trigger Property="RibbonControlService.IsInControlGroup">
                        <Setter Property="Border.BorderBrush" TargetName="OuterBorder">
                            <Setter.Value>
                                <Binding Path="Ribbon.BorderBrush" RelativeSource="{RelativeSource Mode=TemplatedParent}" />
                            </Setter.Value>
                        </Setter>
                        <Setter Property="Border.BorderThickness" TargetName="OuterBorder">
                            <Setter.Value>
                                <Thickness>0,0,1,0</Thickness>
                            </Setter.Value>
                        </Setter>
                        <Setter Property="Border.CornerRadius" TargetName="OuterBorder">
                            <Setter.Value>
                                <CornerRadius>0,0,0,0</CornerRadius>
                            </Setter.Value>
                        </Setter>
                        <Setter Property="Border.CornerRadius" TargetName="InnerBorder">
                            <Setter.Value>
                                <CornerRadius>0,0,0,0</CornerRadius>
                            </Setter.Value>
                        </Setter>
                        <Trigger.Value>
                            <s:Boolean>True</s:Boolean>
                        </Trigger.Value>
                    </Trigger>
                    <Trigger Property="UIElement.IsEnabled">
                        <Setter Property="UIElement.Opacity" TargetName="PART_Image">
                            <Setter.Value>
                                <s:Double>0.5</s:Double>
                            </Setter.Value>
                        </Setter>
                        <Setter Property="TextElement.Foreground" TargetName="OuterBorder">
                            <Setter.Value>
                                <SolidColorBrush>#FF9E9E9E</SolidColorBrush>
                            </Setter.Value>
                        </Setter>
                        <Trigger.Value>
                            <s:Boolean>False</s:Boolean>
                        </Trigger.Value>
                    </Trigger>
                    <DataTrigger Binding="{Binding Path=(SystemParameters.HighContrast)}" Value="True">
                        <Setter Property="TextElement.Foreground" TargetName="OuterBorder">
                            <Setter.Value>
                                <DynamicResource ResourceKey="{x:Static SystemColors.MenuTextBrushKey}" />
                            </Setter.Value>
                        </Setter>
                        <Setter Property="Panel.Background" TargetName="OuterBorder">
                            <Setter.Value>
                                <SolidColorBrush>#00FFFFFF</SolidColorBrush>
                            </Setter.Value>
                        </Setter>
                        <Setter Property="Border.BorderBrush" TargetName="OuterBorder">
                            <Setter.Value>
                                <SolidColorBrush>#00FFFFFF</SolidColorBrush>
                            </Setter.Value>
                        </Setter>
                        <Setter Property="Border.CornerRadius" TargetName="OuterBorder">
                            <Setter.Value>
                                <CornerRadius>0,0,0,0</CornerRadius>
                            </Setter.Value>
                        </Setter>
                    </DataTrigger>
                    <MultiDataTrigger>
                        <MultiDataTrigger.Conditions>
                            <Condition Binding="{Binding Path=IsMouseOver, RelativeSource={RelativeSource Mode=TemplatedParent}}" Value="True" />
                            <Condition Binding="{Binding Path=(SystemParameters.HighContrast)}" Value="True" />
                        </MultiDataTrigger.Conditions>
                        <Setter Property="Border.BorderBrush" TargetName="OuterBorder">
                            <Setter.Value>
                                <DynamicResource ResourceKey="{x:Static SystemColors.ControlLightBrushKey}" />
                            </Setter.Value>
                        </Setter>
                    </MultiDataTrigger>
                    <MultiDataTrigger>
                        <MultiDataTrigger.Conditions>
                            <Condition Binding="{Binding Path=IsMouseOver, RelativeSource={RelativeSource Mode=TemplatedParent}}" Value="True" />
                            <Condition Binding="{Binding Path=IsEnabled, RelativeSource={RelativeSource Mode=Self}}" Value="False" />
                            <Condition Binding="{Binding Path=(SystemParameters.HighContrast)}" Value="True" />
                        </MultiDataTrigger.Conditions>
                        <Setter Property="Border.BorderBrush" TargetName="OuterBorder">
                            <Setter.Value>
                                <DynamicResource ResourceKey="{x:Static SystemColors.GrayTextBrushKey}" />
                            </Setter.Value>
                        </Setter>
                    </MultiDataTrigger>
                    <MultiDataTrigger>
                        <MultiDataTrigger.Conditions>
                            <Condition Binding="{Binding Path=IsDropDownOpen, RelativeSource={RelativeSource Mode=TemplatedParent}, FallbackValue=false}" Value="True" />
                            <Condition Binding="{Binding Path=IsEnabled, RelativeSource={RelativeSource Mode=Self}}" Value="False" />
                            <Condition Binding="{Binding Path=(SystemParameters.HighContrast)}" Value="True" />
                        </MultiDataTrigger.Conditions>
                        <Setter Property="Border.BorderBrush" TargetName="OuterBorder">
                            <Setter.Value>
                                <DynamicResource ResourceKey="{x:Static SystemColors.ControlLightBrushKey}" />
                            </Setter.Value>
                        </Setter>
                    </MultiDataTrigger>
                    <MultiDataTrigger>
                        <MultiDataTrigger.Conditions>
                            <Condition Binding="{Binding Path=IsMouseOver, RelativeSource={RelativeSource Mode=Self}}" Value="True" />
                            <Condition Binding="{Binding Path=(SystemParameters.HighContrast)}" Value="True" />
                        </MultiDataTrigger.Conditions>
                        <Setter Property="Panel.Background" TargetName="OuterBorder">
                            <Setter.Value>
                                <DynamicResource ResourceKey="{x:Static SystemColors.HighlightBrushKey}" />
                            </Setter.Value>
                        </Setter>
                        <Setter Property="Border.BorderBrush" TargetName="OuterBorder">
                            <Setter.Value>
                                <DynamicResource ResourceKey="{x:Static SystemColors.ControlLightBrushKey}" />
                            </Setter.Value>
                        </Setter>
                        <Setter Property="Border.CornerRadius" TargetName="OuterBorder">
                            <Setter.Value>
                                <CornerRadius>0,0,0,0</CornerRadius>
                            </Setter.Value>
                        </Setter>
                        <Setter Property="Border.BorderBrush" TargetName="InnerBorder">
                            <Setter.Value>
                                <SolidColorBrush>#00FFFFFF</SolidColorBrush>
                            </Setter.Value>
                        </Setter>
                        <Setter Property="TextElement.Foreground" TargetName="OuterBorder">
                            <Setter.Value>
                                <DynamicResource ResourceKey="{x:Static SystemColors.HighlightTextBrushKey}" />
                            </Setter.Value>
                        </Setter>
                    </MultiDataTrigger>
                    <MultiDataTrigger>
                        <MultiDataTrigger.Conditions>
                            <Condition Binding="{Binding Path=IsKeyboardFocused, RelativeSource={RelativeSource Mode=Self}}" Value="True" />
                            <Condition Binding="{Binding Path=(SystemParameters.HighContrast)}" Value="True" />
                        </MultiDataTrigger.Conditions>
                        <Setter Property="Panel.Background" TargetName="OuterBorder">
                            <Setter.Value>
                                <DynamicResource ResourceKey="{x:Static SystemColors.HighlightBrushKey}" />
                            </Setter.Value>
                        </Setter>
                        <Setter Property="Border.BorderBrush" TargetName="OuterBorder">
                            <Setter.Value>
                                <DynamicResource ResourceKey="{x:Static SystemColors.ControlLightBrushKey}" />
                            </Setter.Value>
                        </Setter>
                        <Setter Property="Border.CornerRadius" TargetName="OuterBorder">
                            <Setter.Value>
                                <CornerRadius>0,0,0,0</CornerRadius>
                            </Setter.Value>
                        </Setter>
                        <Setter Property="Border.BorderBrush" TargetName="InnerBorder">
                            <Setter.Value>
                                <SolidColorBrush>#00FFFFFF</SolidColorBrush>
                            </Setter.Value>
                        </Setter>
                        <Setter Property="TextElement.Foreground" TargetName="OuterBorder">
                            <Setter.Value>
                                <DynamicResource ResourceKey="{x:Static SystemColors.HighlightTextBrushKey}" />
                            </Setter.Value>
                        </Setter>
                    </MultiDataTrigger>
                    <MultiDataTrigger>
                        <MultiDataTrigger.Conditions>
                            <Condition Binding="{Binding Path=IsPressed, RelativeSource={RelativeSource Mode=Self}}" Value="True" />
                            <Condition Binding="{Binding Path=(SystemParameters.HighContrast)}" Value="True" />
                        </MultiDataTrigger.Conditions>
                        <Setter Property="Panel.Background" TargetName="OuterBorder">
                            <Setter.Value>
                                <DynamicResource ResourceKey="{x:Static SystemColors.HighlightBrushKey}" />
                            </Setter.Value>
                        </Setter>
                        <Setter Property="Border.BorderBrush" TargetName="OuterBorder">
                            <Setter.Value>
                                <DynamicResource ResourceKey="{x:Static SystemColors.ControlDarkBrushKey}" />
                            </Setter.Value>
                        </Setter>
                        <Setter Property="Border.CornerRadius" TargetName="OuterBorder">
                            <Setter.Value>
                                <CornerRadius>0,0,0,0</CornerRadius>
                            </Setter.Value>
                        </Setter>
                        <Setter Property="TextElement.Foreground" TargetName="OuterBorder">
                            <Setter.Value>
                                <DynamicResource ResourceKey="{x:Static SystemColors.HighlightTextBrushKey}" />
                            </Setter.Value>
                        </Setter>
                    </MultiDataTrigger>
                    <MultiDataTrigger>
                        <MultiDataTrigger.Conditions>
                            <Condition Binding="{Binding Path=IsInControlGroup, RelativeSource={RelativeSource Mode=Self}}" Value="True" />
                            <Condition Binding="{Binding Path=(SystemParameters.HighContrast)}" Value="True" />
                        </MultiDataTrigger.Conditions>
                        <Setter Property="Border.BorderBrush" TargetName="OuterBorder">
                            <Setter.Value>
                                <DynamicResource ResourceKey="{x:Static SystemColors.ControlLightLightBrushKey}" />
                            </Setter.Value>
                        </Setter>
                    </MultiDataTrigger>
                    <MultiDataTrigger>
                        <MultiDataTrigger.Conditions>
                            <Condition Binding="{Binding Path=IsEnabled, RelativeSource={RelativeSource Mode=Self}}" Value="False" />
                            <Condition Binding="{Binding Path=(SystemParameters.HighContrast)}" Value="True" />
                        </MultiDataTrigger.Conditions>
                        <Setter Property="TextElement.Foreground" TargetName="OuterBorder">
                            <Setter.Value>
                                <DynamicResource ResourceKey="{x:Static SystemColors.GrayTextBrushKey}" />
                            </Setter.Value>
                        </Setter>
                    </MultiDataTrigger>
                </ControlTemplate.Triggers>
            </ControlTemplate>
        </Setter.Value>
    </Setter>
</Style>
RogerN
  • 3,761
  • 11
  • 18
0

Try to use vector graphics. there are allot of tools that you could use to generate a xaml equivalent of this kind of images you can take a look at this article it might help a little.

Allan Chua
  • 9,305
  • 9
  • 41
  • 61
  • 1
    Could be a possible solution but WPF supports PNG:s and you should't need to convert them to vector graphics to be able to use them in the Ribbon. – vanos May 30 '12 at 13:44
  • @vanos your right buddy WPF supports PNG. but the question is PNG capable of shrinking or expanding without getting pixelated? if you use vector graphics as a XAML in a resource dictionary you can even reuse those images without doing the scaling thing everytime you need a smaller or larger copy of it. – Allan Chua May 30 '12 at 13:47
  • I was hoping WPF could resize the PNG:s properly, beacuse with WinForms this was a none issue. In my project i have >100 images so my last option would be to manipulate them in some way. – vanos May 30 '12 at 13:54
  • @vanos I think fixing those 100 images will be the best way.. just a suggestion. Base on experience killing the root cause of the problem solves the problem most rather that making a dirty work around every time a new issue comes out. – Allan Chua May 30 '12 at 13:58
  • Resizing the 100 images in advance would be a lot easier than redrawing them as vector graphics! SVGs are already vector graphics (however like xaml they can contain raster formats) - the article won't help converting pngs to vectors. – Danny Varod May 30 '12 at 18:50
  • @DannyVarod search for VectorMagic App. this can convert images to SVG types without doing complicated process.\ – Allan Chua May 31 '12 at 02:22
  • I think i have to go resizing my images. i found an article from Microsoft [link](http://msdn.microsoft.com/en-us/library/windows/desktop/dd316921(v=vs.85).aspx) with recommended DPI settings for different sizes. 48x48 should have 144 DPI (my pictures has 96 DPI). I don't understand this because shrinking an image should'n be a problem, i mean in WinForms it worked perfectly. But anyway, if resizing my large images to 32x32 will do the magic i will stick with that. – vanos May 31 '12 at 06:30
  • Images DPI settings are for printing, not displaying. Windows DPI settings are what count for displaying and that is 96 by default (and can only be changed globally, not per image). – Danny Varod May 31 '12 at 06:34
  • **Problem "solved"** I randomly picked a couple of images and resized them to 32x32 and they look as expected (good) in the Ribbon. Conclusion: Microsoft has changed something with the imagescaling in WPF (from WinForms) to the worse. – vanos May 31 '12 at 09:17
  • @vanos thanks god... this also worked for me.. i have been getting mad on trying several PathToImageSource Renderings wich all were looking good in normal Image objects. **Thank you for posting this** – LuckyLikey Apr 28 '17 at 12:29
0

What operating system are you using? - WPF doesn't look as good over XP (not a problem with Vista and 7). I believe that this is due to how the default for anti-aliasing differs between XP and the newer operating systems.

Set the width and height in the XAML to 48 to match the image size (also check the stretch parameter).

With 48x48 32bit PNGs the images should look fine.

Since the ribbon bar is not stretched vector graphics are redundant.

If the above does not help, try setting the align to device pixels and setting the LayoutRounding.

As I suggested in my comment, you could resize the images to the display size, however, it should be set explicitly in the XAML, to make sure that is the same.

You can also get WPF to resize the images explicity by setting the height or width to 32 and using a ScaleTransform.

Community
  • 1
  • 1
Danny Varod
  • 17,324
  • 5
  • 69
  • 111
  • Thanks for the reply, i will try them. I'm using Windows 7. Even if my source images are 48x48 i don't want to display the full size on the ribbon. It will take too much space, i just wan't them to be resized properly. – vanos May 30 '12 at 13:38
  • Did you try the align to device pixels property? – Danny Varod May 31 '12 at 06:37
  • I don't know about the vote down, it wasn't me... Yes i tried the align to device pixels without any effect... – vanos May 31 '12 at 06:59
  • Then try LayoutRounding (see new link in answer). – Danny Varod May 31 '12 at 07:09
  • i'm afraid LayoutRounding is not possible to use because im stuck in framework 3.5... I begin to wonder if the settings are only compatible with Windows Aero? My developing machine is a virtual machine (company policy) and Windows Aero is disabled on those machines. Maybe this could explain why none of the settings are working? – vanos May 31 '12 at 07:35
  • Yes, it does. That is the reason I first asked which OS version you are using. The fast yet less accurate anti aliasing was added in .NET 4.0, in .NET 3.5 the default was the more accurate non-default setting in 4.0. Next time added framework version and OS configuration to your questions. – Danny Varod May 31 '12 at 09:46
  • I still think you should try setting the images via XAML and not code a. because that is better design, b. it will be easier to see what you are and are not doing. Also your question doesn't say what the size settings are. – Danny Varod May 31 '12 at 09:49
  • It's true i could have been more clear about what FW and operation system i was using in the question. But i mentioned in my question *MS RibbonControlsLibrary (3.5.41019.1)* by that you could see what framework i'm using. Further, i specified the source image size in the question. I don't understand what you mean, the less accurate AA was added in FW4.0 but i'm using FW3.5, so it shouldn't effect my application. I agree about setting the images from XAML would be easier but my menu source (dataset) is not "XAML friendly" and the code existed from the old WinForm based window. – vanos May 31 '12 at 10:05
0

I had the same problem and I created my own usercontrol to solve this.

This is how I did it:

<ribbon:Ribbon>
        <ribbon:RibbonTab Header="File">
            <ribbon:RibbonGroup Header="File">
                <views:ImageButton Command="{Binding LoadCommand}" Caption="Open" SourceImage="/Images/save.png"/>
            </ribbon:RibbonGroup>
        </ribbon:RibbonTab>
    </ribbon:Ribbon>

The image button usercontrol ImageButton.xaml

<UserControl Name="control"

 <Button Command="{Binding Command, ElementName=control}" Style="{x:Null}">
    <StackPanel>
        <infrastructure:AutoGreyableImage Width="32" Source="{Binding SourceImage, ElementName=control}"/>
        <TextBlock Text="{Binding Caption, ElementName=control}"/>
    </StackPanel>
</Button>

The image button usercontrol ImageButton.xaml.cs

public partial class ImageButton : UserControl
{
    public static DependencyProperty CommandProperty = DependencyProperty.Register(
      "Command", typeof(ICommand), typeof(ImageButton));
    public static DependencyProperty SourceProperty = DependencyProperty.Register(
      "SourceImage", typeof(string), typeof(ImageButton));
    public static DependencyProperty CaptionProperty = DependencyProperty.Register(
      "Caption", typeof(string), typeof(ImageButton));

    public ICommand Command
    {
        get
        {
            return (ICommand)GetValue(CommandProperty);
        }
        set
        {
            SetValue(CommandProperty, value);
        }

    }
    public string SourceImage
    {
        get
        {
            return (string)GetValue(SourceProperty);
        }
        set
        {
            SetValue(SourceProperty, value);
        }

    }
    public string Caption
    {
        get
        {
            return (string)GetValue(CaptionProperty);
        }
        set
        {
            SetValue(CaptionProperty, value);
        }

    }
    public ImageButton()
    {
        InitializeComponent();
    }
}

For the AutogreyableImage, I used this post

This is a copy paste of the class

    using System.Windows.Controls;
    using System.Windows.Media;
    using System.Windows.Media.Imaging;  


/// <summary>
    /// Class used to have an image that is able to be gray when the control is not enabled.
    /// Author: Thomas LEBRUN (http://blogs.developpeur.org/tom)
    /// </summary>
    public class AutoGreyableImage : Image
    {

        /// <summary>
        /// Initializes a new instance of the <see cref="AutoGreyableImage"/> class.
        /// </summary>
        static AutoGreyableImage()
        {
            // Override the metadata of the IsEnabled property.
            IsEnabledProperty.OverrideMetadata(typeof(AutoGreyableImage), new FrameworkPropertyMetadata(true, new PropertyChangedCallback(OnAutoGreyScaleImageIsEnabledPropertyChanged)));
        }

        /// <summary>
        /// Called when [auto grey scale image is enabled property changed].
        /// </summary>
        /// <param name="source">The source.</param>
        /// <param name="args">The <see cref="System.Windows.DependencyPropertyChangedEventArgs"/> instance containing the event data.</param>
        private static void OnAutoGreyScaleImageIsEnabledPropertyChanged(DependencyObject source, DependencyPropertyChangedEventArgs args)
        {
            var autoGreyScaleImg = source as AutoGreyableImage;
            var isEnable = Convert.ToBoolean(args.NewValue);
            if (autoGreyScaleImg != null)
            {
                if (!isEnable)
                {
                    // Get the source bitmap
                    var bitmapImage = new BitmapImage(new Uri(autoGreyScaleImg.Source.ToString()));
                    // Convert it to Gray
                    autoGreyScaleImg.Source = new FormatConvertedBitmap(bitmapImage, PixelFormats.Gray32Float, null, 0);
                    // Create Opacity Mask for greyscale image as FormatConvertedBitmap does not keep transparency info
                    autoGreyScaleImg.OpacityMask = new ImageBrush(bitmapImage);
                }
                else
                {
                    // Set the Source property to the original value.
                    autoGreyScaleImg.Source = ((FormatConvertedBitmap)autoGreyScaleImg.Source).Source;
                    // Reset the Opcity Mask
                    autoGreyScaleImg.OpacityMask = null;
                }
            }
        }
    }

I hope this will help you and the others coming

Community
  • 1
  • 1
Daniel
  • 9,312
  • 3
  • 48
  • 48