масштабирование размера шрифта в универсальном приложении Магазина Windows (W8.1 + WP8.1)

Как масштабировать текст в универсальном приложении Магазина Windows (W8.1 + WP8.1)? По сути, приложение должно выглядеть одинаково независимо от используемого устройства/разрешения. Текущая ситуация такова, что макет (макет на основе динамической сетки) и изображения хорошо масштабируются, за исключением текста (размер шрифта).

Отображаемый текст выглядит красиво для разрешения WVGA (480 × 800), но невероятно мал для разрешения 1080p.

Я уже прочитал много материалов, таких как рекомендации по масштабированию до плотности пикселей или Рекомендации по поддержке нескольких размеров экрана

Но я до сих пор не знаю, как масштабировать текст, чтобы он оставался читаемым независимо от разрешения экрана / DPI.

Конечно, я мог бы написать класс, который использует DisplayInformation. ResolutionScale для преобразования размера шрифта в соответствующее значение.

пример:

  • FontSize 16 на WVGA с ScaleFactor 1x равен FontSize 16
  • FontSize 16 на WXGA с ScaleFactor 1.6x равен FontSize 25,6
  • FontSize 16 на 720p с ScaleFactor 1.5x равен FontSize 24
  • FontSize 16 на 1080p с ScaleFactor 2.25x равен FontSize 36

Но я не уверен, что это будет работать для всех сценариев. Есть ли лучший способ сделать это? Я думал, что такая обычная задача может быть выполнена с некоторыми встроенными функциями.

Отказ от ответственности: это (надеюсь) не «позвольте мне погуглить этот вопрос для вас». Я нашел множество страниц, посвященных масштабированию, но все они охватывают макет или изображения. Но я не мог найти ничего о масштабировании размера шрифта. Пожалуйста, простите меня, если я что-то упустил.


Редактировать: Боюсь, я не смог четко выразить проблему: (WVGA слева, 1080p справа) WVGA против 1080p


comment
Вы решили это? У меня такая же проблема, и я не могу найти никакой хорошей информации.   -  person Andreas Bergqvist    schedule 26.09.2014
comment
Нет, я не делал. Мне интересно, как другие разработчики решили эту проблему. Может, мы лаем не на то дерево?   -  person Joel    schedule 29.11.2014
comment
Похоже у меня тоже такая проблема, не могу найти решение...   -  person Laserson    schedule 16.12.2014


Ответы (5)


Что я сделал для своего приложения Магазина Windows, так это привязал свойство FontSize к высоте страницы и преобразовал значение (вам придется немного поиграть, пока вы не найдете правильное значение для вашего случая).

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

А вот мой класс Converter

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

Это не идеально, но работает довольно хорошо, пока я не найду более красивое решение.

person smeshko    schedule 29.06.2014

Я обнаружил, что с помощью 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>
person Nick Banks    schedule 22.03.2015

WinRT может автоматически масштабировать все, что работает поверх него, и будет делать это в зависимости от плотности пикселей дисплея. В Windows 8.0 он масштабировался на 100%, 140% и 180%. Более новая версия может иметь еще больше коэффициентов масштабирования. Я не верю, что вы можете отказаться от этого масштабирования.

Если вы не заинтересованы в использовании встроенного масштабирования, которое работает на системном уровне, то вы вынуждены делать все самостоятельно. Вы можете масштабировать текст вручную, установив размер шрифта, или вы можете использовать силу преобразований для масштабирования текста или всего пользовательского интерфейса.

person Kasper Holdum    schedule 14.04.2014
comment
пользовательский интерфейс масштабируется без проблем. Проблема в размере шрифта. Как включить масштабирование размера шрифта в W8.1, WP8.1? - person Joel; 14.04.2014
comment
Размер шрифта также автоматически масштабируется WinRT. Попробуйте зайти в «Настройки» -> «ПК и устройства» -> «Экран» -> «Дополнительные параметры», выберите «По умолчанию / больше» и посмотрите разницу. - person Kasper Holdum; 15.04.2014

Ваши образцы изображений вводят в заблуждение, потому что фактический размер устройств также будет другим. В этой записи блога рассказывается, как настроить эмуляторы для более точного представления.

Если вы хотите, чтобы на каждом экране отображался один и тот же контент (например, 6-дюймовый телефон просто показывает увеличенную версию 4-дюймового телефона, а не показывает на 50 % больше контента), используйте ViewBox для масштабирования приложения. Однако это не особенно хороший пользовательский опыт.

person Peter Torr - MSFT    schedule 06.01.2015

Я жду ответа на этот вопрос и сам задал соответствующий вопрос.
В качестве временного решения я использовал 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();
}}

Надеюсь, это поможет...

person PythonesqueSpam    schedule 29.11.2014