I am working on a Windows application using WPF Ribbons. On these ribbons, there are controls with images, which are specified by (Large/Small)ImageSource, just like in this sample:
<Ribbon>
...
<RibbonGroup>
<RibbonToggleButton Name="NotExecutedQCButton" Margin="8,0,8,0"
Command="{Binding FilterNotExecutedCommand}"
IsChecked="{Binding NotExecutedChecked, Mode=TwoWay}"
LargeImageSource="pack://application:,,,/Sensor.UserControls;component/Icons/icons8.com/qc_notExecuted.png"
Label="Not Executed"/>
<RibbonButton Name="AllQCButton" Margin="8,0,8,0"
Command="{Binding FilterAllCommand}"
LargeImageSource="pack://application:,,,/Sensor.UserControls;component/Icons/icons8.com/qc_erase.png"
Label="Remove Filters"/>
</RibbonGroup>
...
Now when I use 48x48 pixel images here, they show up blurry and distorted. Just like here:
Images do not render correctly in WPF ribbon control
When I rescale the images to 32x32, it shows up fine. This is due to the RibbonImageSize having a fixed value which can be found here:
According to this doc:
A Small image is typically 16x16 pixels at 96 dpi. A Large image is typically 32x32 pixels at 96 dpi.
Notice the word "typically". When doing some further research, this value seems to depend on the dpi of the monitor being used:
https://learn.microsoft.com/en-us/windows/desktop/windowsribbon/windowsribbon-imageformats
This document states that I need to provide differently scaled versions of the image to support different monitors, like this:
<Command.LargeImages>
<Image Source="res/CutLargeImage32.bmp" Id="116" Symbol="ID_CUT_LARGEIMAGE1" MinDPI="96" />
<Image Source="res/CutLargeImage40.bmp" Id="117" Symbol="ID_CUT_LARGEIMAGE2" MinDPI="120" />
<Image Source="res/CutLargeImage48.bmp" Id="118" Symbol="ID_CUT_LARGEIMAGE3" MinDPI="144" />
<Image Source="res/CutLargeImage64.bmp" Id="119" Symbol="ID_CUT_LARGEIMAGE4" MinDPI="192" />
</Command.LargeImages>
Now where do I put this code in my example? I don't have a Command in my code like in the example, and the RibbonButton or other Ribbon control elements do not have a LargeImages property.
Or better, how can I know for sure these fixed values of 16x16 or 32x32 are always being used? If I can't, how can I provide these values for the ribbon controls in my applications? Right now I'm not interested in having different sizes across monitors and I'm fine with using one hard-coded resolution for all the images (one for small, one for large) on every monitor. But now it seems that when I run my application on a machine with a different monitor, the images might be blurry. Even when I manage to specify images for all these four cases, it will not work on monitors that do not have one of these four specified DPI values.
All I want is to be sure that these images are not blurry, at least on standard modern monitors. How can I achieve this?
Or better, how can I know for sure these fixed values of 16x16 or 32x32 are always being used?
Look in the default ControlTemplate
for the control. You'll find it in the System.Windows.Controls.Ribbon.dll
assembly which is located in C:\Windows\Microsoft.NET\Framework64\v4.0.30319\WPF.
If you decompile it using a tool such as dokPeek and look at the templates in the themes folder, you will notice that the Image
elements that bind to the LargeImageSource
property has a fixed width and weight of 32
and that the images that display the SmallImageSource
has a fixed widht and heigt of 16
.
You probably want to modify the templates if you intend to display images of any other sizes.