How do i scale text in Windows Store Universal App (W8.1 + WP8.1)? Basically, the app should look the same regardless which device/resolution is used. The current situation is that layout (dynamic grid based layout) and images scale well except of the text (font size).
The text displayed looks nice for WVGA resolution (480 × 800) but is incredible small for 1080p resolution.
I already read a lot of stuff like Guidelines for scaling to pixel density or Guidelines for supporting multiple screen sizes
But i still don't know how to scale text to stay readable regardless of display resolution/DPI.
Of course i could write a class which uses the DisplayInformation.ResolutionScale property to convert the font size to an appropriated value.
example:
- FontSize 16 on WVGA with ScaleFactor 1x equals FontSize 16
- FontSize 16 on WXGA with ScaleFactor 1.6x equals FontSize 25,6
- FontSize 16 on 720p with ScaleFactor 1.5x equals FontSize 24
- FontSize 16 on 1080p with ScaleFactor 2.25x equals FontSize 36
But I'm uncertain if this will work for all scenarios. Is there a better way to do so? I thought such a common task could be performed with some build in functionality.
Disclaimer: this is (hopefully) not a "let me google this for you question" I found tons of pages which are about scaling but they all cover the layout or images. But I couldn't find anything about font size scaling. Please forgive me if I missed something.
Edit: I'm afraid, i failed to express the problem clearly: (WVGA on the left, 1080p on the right)
What I did for my Windows Store app was to bind the FontSize property to the page height and convert the value (you'd have to play a bit, until you find the right value for your case).
<TextBlock Grid.Row="0" Text="Some Text"
FontSize="{Binding ElementName=pageRoot, Path=ActualHeight,
Converter={StaticResource PageHeightConverter}, ConverterParameter='BodyFontSize'}" />
And here's my Converter class
class PageHeightConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, string language)
{
switch ((string)parameter)
{
case "HeroImage":
return ((((double)value) * 2) / 3);
case "TitleFontSize":
return (int)((double)value / 40);
case "BodyFontSize":
return (int)((double)value / 60);
default:
return 0;
}
}
}
It's not perfect, but works pretty well until I find a perttier solution.
I found that using the IValueConverter method worked pretty well when used in conjunction with the ResolutionScale property:
class ScaleConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, string language)
{
var resolutionScale = (int)DisplayInformation.GetForCurrentView().ResolutionScale / 100.0;
var baseValue = int.Parse(parameter as string);
var scaledValue = baseValue * resolutionScale;
if (targetType == typeof(GridLength))
return new GridLength(scaledValue);
return scaledValue;
}
}
Please note, that if you use for more than FontSize (as I am also using it for ColumnDefinition.Width) you will need to handle returning the proper Type'ed output.
My XAML usage looks something like this:
<TextBlock Text="string" FontSize="{Binding ElementName=root, Path=ActualHeight, Converter={StaticResource ScaleConverter}, ConverterParameter='30'}" />
And to just complete the solution, for each XAML page you use this on, you need to include the following, replacing SwapChainBackgroundPanel with whatever class you are using, and defining the xml namespace properly:
<SwapChainBackgroundPanel.Resources>
<local:ScaleConverter x:Key="ScaleConverter"></local:ScaleConverter>
</SwapChainBackgroundPanel.Resources>
WinRT can automatically scale everything running on top of it and will do so based on the display's pixel density. In Windows 8.0 it used to scale in 100%, 140% and 180%. Newer version might have even more scale factors. I do not believe that you can opt out of this scaling.
If you are not interested in using the built-in scaling which operates on a system level, then you are pretty much forced to do everything yourself. You can scale the text manually by setting the font size or you can use the power of transforms to scale either your text or your whole UI.
Your sample images are misleading because the actual size of the devices would be different as well. This blog post tells you how to setup emulators for a more accurate representation.
If you want the exact same content on every screen (ie, a 6" phone just shows a blown-up version of a 4" phone, rather than showing 50% more content) then use a ViewBox
to scale your app. This is not a particularly good user experience though.
I'm waiting for an answer to this and have posted a related question myself.
As an interim solution I used an iValueConverter and this works at certain resolutions but not others.
My iValueConverter is as follows:
class FontSizeConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, string language)
{
var display = Helpers.ScreenResolution();
var height = display.Height;
var oldFontSize = (int)value;
if(oldFontSize == null) return;
// Calculate the new Fontsize based on the designed Fontsize
// and design display size in Visual Studio designer...
var newFontSize = (int)Math.Round((oldFontSize / 768.0) * height, 0);
return newFontSize;
}
public object ConvertBack(object value, Type targetType, object parameter, string language)
{
throw new NotImplementedException();
}}
I hope this helps...
来源:https://stackoverflow.com/questions/23041883/font-size-scaling-in-windows-store-universal-app-w8-1-wp8-1