Click here to Skip to main content
15,915,680 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
See more:
Hi,
I've read loads of MSDN pages on scaling, fonts, UI etc. but none address the issue of fonts and scaling together. In fact I've found nothing in web searches that covers both. For the moment I've resorted to an iValueConverter for the FontSize that uses the following logic:

(FontSize that looks Ok at 1366x768 resolution) / (Screen Height at 1366x768 resolution) x (Screen Height at Runtime) =>
C#
var newFontSize = (int)Math.Round((oldFontSize / 768.0) * screenHeight, 0);

This iValueConverter is then applied like this:
HTML
<TextBlock x:Name="BackgroundTextBlock" Grid.Column="1"
Text="{Binding [Ads/BackgroundText], Source={StaticResource Localised}}"
FontSize="{Binding Converter={StaticResource SizeConverter}, ConverterParameter={StaticResource AdBackgroundFontSize}, FallbackValue={StaticResource AdBackgroundFontSize}}"
TextWrapping="WrapWholeWords" VerticalAlignment="Center" HorizontalAlignment="Center" TextAlignment="Center" />

I'm using Visual Studio with the design view resolution or 1366x768. Running the App on my Laptop at 1920x1080 resolution the fonts where fine using the iValueConverter to enlarge them. However, I found that on testing the app on a friends PC with a resolution somewhere between 1366x768 and 1920x1080 the fonts where much too large. So it seems, either my logic needs to be more complicated to take account of different scaling at other display resolutions or the iValueConverter approach is not the correct one! I've also replicated similar iValueConverters for such things as Thickness as applied to borders and margins.

Has anyone any advice of how I should be doing effective scaling of all screen artefacts?

Thanks in advance...
Posted
Updated 2-Dec-15 11:00am
v2

Yes, with WPF you can scale all the artifacts, including characters. But are you sure you really want it? If you use such application with always maximized window, you will get the following effect: for different screen sizes, you will get the same relative character size, relative to one of the two, pixel width or pixel height of the screen. With not very different aspect ratio specs of different devices, it will give you the look scaled to each physical screen nicely. But, from the other hand, the user will screw up the view way too much trying to resize the window down; however, you can curb it by using minimum size (MinWidth, MinHeight properties). This problem will be another flip of the coin.

For comparison, I prepared two XAML samples for your. First will scale all elements to the Window size, but not characters, which I formatted to different sizes, to demonstrate the behavior:
HTML
<Window x:Class="Scaling.Ui.MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    Title="MainWindow" Height="300" Width="300">
        <DockPanel LastChildFill="True">
            <TextBlock DockPanel.Dock="Top">One element</TextBlock>
            <TextBlock DockPanel.Dock="Top" FontSize="20">Another element</TextBlock>
            <TextBlock DockPanel.Dock="Top">Smaller element again</TextBlock>
            <TextBlock DockPanel.Dock="Top" FontSize="16">Enter text below:</TextBlock>
            <Border BorderBrush="Black" BorderThickness="1">
                <TextBox/>
            </Border>
        </DockPanel>
</Window>


Now, it all will be graphically scaled, with characters, if you add ViewBox — this is the key. Try it now:
HTML
<Window x:Class="Scaling.Ui.MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    Title="MainWindow" Height="300" Width="300">
    <Viewbox>
        <DockPanel LastChildFill="True">
            <TextBlock DockPanel.Dock="Top">One element</TextBlock>
            <TextBlock DockPanel.Dock="Top" FontSize="20">Another element</TextBlock>
            <TextBlock DockPanel.Dock="Top">Smaller element again</TextBlock>
            <TextBlock DockPanel.Dock="Top" FontSize="16">Enter text below:</TextBlock>
            <Border BorderBrush="Black" BorderThickness="1">
                <TextBox/>
            </Border>
        </DockPanel>
    </Viewbox>
</Window>


The good thing about ViewBox is: it is fully agnostic about its content element; graphic and text elements are treated equally, the whole visual tree of the content is treated as graphics. Well, this is good way to show vector graphics, which can be any Canvas element with any other elements nested inside. But it could be anything else.

And you can combine these approaches, because you can show some part of the window under ViewBox and some not. Besides, you can change all fonts in response to change of rendered size; it can be done using binding or code behind, or both. I warned you about using careful considerations and taking into account all consequences. You decide.

—SA
 
Share this answer
 
v5
Comments
Sergey Alexandrovich Kryukov 2-Dec-15 18:02pm    
I think I will be able to do so if you give me some complete XAML (please, make it as short as possible, focused only on this button problem).
Also, I don't understand why using "*". If the content is button or button set, it should be "Auto". Besides, I don't know what you mean by "very large".

If just "auto" fixes your problem, isn't it the time to accept the answer formally? In all cases, your follow-up questions will be welcome.

—SA
FrontrunnerSoftwareIreland 2-Dec-15 18:05pm    
How do I get comments on the codeproject page to accept code? when I paste XAML it interprets it as HTML :(
Also how do I show a screen-capture if I can't submit an image file in comments?
Sergey Alexandrovich Kryukov 2-Dec-15 19:27pm    
Oh...

You can do it in different way. First of all, <pre lang="HTML"> is correct markup for XML. This is just how this site syntax coloring works, but, come to thing about, there is no a need to distinguish between HTML and XML, in this respect.

Now, you code has mangled in the post submission process. It happens mostly because you cannot really use < > on HTML page (it should be clear why), you need to escape it like &lt; &gt;

Now, on top of it, things are mangled because you allowed them to. On right, there is a request on how to format input by paste: "Paste as". The clearest fully controlled way would be "as is", and then you have to escape HTML character entities manually. It's the best to do it separately, in some editor, before posting. Another option is "Best guess" or "Code Block", but this automation will do what it normally does, so you need to keep an eye on it.

Now, this is about your question post. In comments, there is nothing like that. So, better don't put any code, or maybe put some simplest inline code fragments in "code" tags, and manually escape HTML characters. Many HTML features won't be accepted in comments, so keep it simple.

In question posts, articles, you have a lot of more of formatting operational, but also not all. Frames, comments, scripts, and some other features will be auto-removed.

—SA
FrontrunnerSoftwareIreland 14-Dec-15 9:04am    
I removed all star (*) references and tried to scale the entire page with a Viewbox as you suggested and all screen artefacts scaled correctly, but only after a pause of a few seconds whilst some Timer/Canvas based screen animations occur, that activate in the OnGotFocus method for the page. During this time the screen artefacts are not scaled correctly and look odd. This pause in the operation of Viewbox, renders it useless.
Sergey Alexandrovich Kryukov 14-Dec-15 11:31am    
I have too vague understanding what code caused such problems. One of the ways to explain it would be development of the minimized code manifesting this problem. It really should become very small, manageable, but it should work and presented comprehensively. Just one thing, "Timer" looks suspicious, because timers cause many problems and hardly should be used for animation; a separate thread is much smoother way to develop animation...
—SA
Keep in mind that modern fonts (.otf, .ttf, etc.) use special dynamic adjustment of the glyphs ("hinting") so their appearance is optimized for readability when rendered at certain smaller sizes (typically 9~14 points).

While I hope you will find what you need in Sergey's excellent answer here, I would argue (and, I don't use WPF, so that's one disclaimer) that trying to dynamically scale Fonts in a Windows app is a mistake that will lead to weird looking Text when smaller point sizes are used.

imho, if you try to implement dynamic scaling and ignore this feature of modern fonts, then, yes, that may mean that those visual elements that contain the Text must change size, and, possibly, the entire "ancestor chain" of the changed element must change size ... however, in WPF that kind of scaling response among container visual elements is, I read, I am told, not difficult.

The solution I suggest is to give the user of your application the ability at run-time to change the size of the fonts, selecting from the standard array of point sizes that are designed to look best.
 
Share this answer
 
Comments
FrontrunnerSoftwareIreland 2-Dec-15 23:22pm    
My App is a Universal Windows Store App. I created my app without any scaling code initially but had all sorts of problems getting fonts, margins and sizes to scale properly at differing screen resolutions. I then wrote a load of code to scale everything including button dimensions based on sizes relative to the screen size as that's the only solution I could find. I've tried Viewbox but it doesn't work correctly as it takes a number of seconds on app start to display the screen contents correctly and looks a mess until that happens. So I'm left with the solution I've got now which is code to change screen artefact size based on the screen resolution. It's a pain to do this but until someone suggests a better alternative, I'm stuck with it.
BillWoodruff 3-Dec-15 0:19am    
I empathize with your dilemma here, and, I believe, thousands of Win programmers struggling to make their apps look good on various screen-sizes and resolutions share your problem ... well, it may be even "broader" than that: I'd say programmers working with any modern OS trying to create effective UI's for mobile, desktop, tablet, etc. are all struggling with this.

In the past I have gone as far (in WinForms for desktop) to create different UI's for a small set of common screen resolutions: 800/600, 1024/768, 1360/768.

I suspect the solution Sergey outlines is the best possible for WPF, but I don't use WPF. Hopefully other WPF gurus here will give their opinion.

I haven't looked at what strategies Mono is using for creating UI's on different devices; if I were planning to do cross-platform, cross-device, projects I would examine that.

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



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900