20

如何在 Windows Store Universal App (W8.1 + WP8.1) 中缩放文本?基本上,无论使用哪种设备/分辨率,应用程序看起来都应该相同。目前的情况是布局(基于动态网格的布局)和图像除了文本(字体大小)之外都可以很好地缩放。

显示的文本对于 WVGA 分辨率 (480 × 800) 看起来不错,但对于 1080p 分辨率来说却是令人难以置信的小。

我已经阅读了很多东西,例如 缩放到像素密度的指南或 支持多种屏幕尺寸的指南

但我仍然不知道如何缩放文本以保持可读性,无论显示分辨率/ DPI如何。

当然,我可以编写一个使用DisplayInformation.ResolutionScale属性将字体大小转换为适当值的类。

例子:

  • 具有 ScaleFactor 1x 的 WVGA 上的 FontSize 16 等于 FontSize 16
  • 具有 ScaleFactor 1.6x 的 WXGA 上的 FontSize 16 等于 FontSize 25,6
  • FontSize 16 on 720p with ScaleFactor 1.5x 等于 FontSize 24
  • FontSize 16 on 1080p with ScaleFactor 2.25x 等于 FontSize 36

但我不确定这是否适用于所有情况。有更好的方法吗?我认为这样一个常见的任务可以通过一些内置功能来执行。

免责声明:这(希望)不是“让我用谷歌搜索这个问题”我发现了大量关于缩放的页面,但它们都涵盖了布局或图像。但我找不到任何关于字体大小缩放的信息。如果我遗漏了什么,请原谅我。


编辑:恐怕我没能清楚地表达问题:(左边是WVGA,右边是1080p) WVGA 与 1080p

4

5 回答 5

8

我为我的 Windows 应用商店应用程序所做的是将 FontSize 属性绑定到页面高度并转换值(你必须玩一点,直到你找到适合你的情况的正确值)。

<TextBlock Grid.Row="0" Text="Some Text" 
FontSize="{Binding ElementName=pageRoot, Path=ActualHeight, 
Converter={StaticResource PageHeightConverter}, ConverterParameter='BodyFontSize'}" />

这是我的转换器类

    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;
        }
    }
}

它并不完美,但在我找到更好的解决方案之前效果很好。

于 2014-06-29T20:15:39.503 回答
6

我发现将IValueConverter方法与ResolutionScale属性结合使用时效果很好:

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;
    }
}

请注意,如果您使用的不仅仅是 FontSize(因为我也将它用于 ColumnDefinition.Width),您将需要处理返回正确的 Type'ed 输出。

我的 XAML 用法如下所示:

<TextBlock Text="string" FontSize="{Binding ElementName=root, Path=ActualHeight, Converter={StaticResource ScaleConverter}, ConverterParameter='30'}" />

为了完成解决方案,对于您使用它的每个 XAML 页面,您需要包含以下内容,将 SwapChainBackgroundPanel 替换为您正在使用的任何类,并正确定义 xml 命名空间:

<SwapChainBackgroundPanel.Resources>
    <local:ScaleConverter x:Key="ScaleConverter"></local:ScaleConverter>
</SwapChainBackgroundPanel.Resources>
于 2015-03-22T03:53:59.807 回答
2

WinRT 可以自动缩放在其上运行的所有内容,并将根据显示器的像素密度进行缩放。在 Windows 8.0 中,它曾经以 100%、140% 和 180% 的比例缩放。较新的版本可能有更多的比例因子。我不相信你可以选择退出这种缩放。

如果您对使用在系统级别运行的内置缩放不感兴趣,那么您几乎被迫自己做所有事情。您可以通过设置字体大小手动缩放文本,也可以使用转换的强大功能来缩放文本或整个 UI。

于 2014-04-14T10:17:40.920 回答
1

您的示例图像具有误导性,因为设备的实际尺寸也会不同。这篇博文告诉您如何设置模拟器以获得更准确的表示。

如果您希望在每个屏幕上都显示完全相同的内容(即 6 英寸手机只显示 4 英寸手机的放大版,而不是显示 50% 以上的内容),请使用 aViewBox来扩展您的应用程序。不过,这并不是一个特别好的用户体验。

于 2015-01-06T00:05:01.470 回答
0

我正在等待这个问题的答案,并自己发布了一个相关问题。
作为临时解决方案,我使用了 iValueConverter,它适用于某些分辨率,但不适用于其他分辨率。

我的 iValueConverter 如下:

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();
}}

我希望这有帮助...

于 2014-11-29T16:10:23.533 回答