Арифметические операции внутри словаря ресурсов XAML

Что я хочу сделать

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

Я уже хорошо использую OnPlatform и OnIdiom для разных аспектов, например FontSize.

Для платформы iOS я хотел бы сделать HeightRequest записи 20+(FontSize). FontSize уже настроен с помощью OnIdiom (для планшетов он немного увеличен).

В идеальном мире основная вещь, которую я пытаюсь сделать, может выглядеть примерно как
. <Setter Property = "HeightRequest" Value = "{DynamicResource StandardFontSize}+10">

Что работает"

У меня есть решение работающий, если я использую комбинацию OnIdiom и OnPlatform.

<?xml version = "1.0" encoding = "utf-8" ?>
<Application xmlns = "http://xamarin.com/schemas/2014/forms"
             xmlns:x = "http://schemas.microsoft.com/winfx/2009/xaml"
             x:Class = "XamarinDesigner.App"
             xmlns:local = "clr-namespace:XamarinDesigner"
             >
    <Application.Resources>
        <ResourceDictionary>
            <OnIdiom x:Key = "StandardFontSize" x:TypeArguments = "x:Double"  Tablet = "22" Phone = "18"/>
            <Style x:Key = "MyEntry" TargetType = "Entry">
                <Setter Property = "FontSize" Value = "{DynamicResource StandardFontSize}"/>
                <Setter Property = "HeightRequest">
                    <Setter.Value>
                        <OnIdiom x:TypeArguments = "x:Double">
                            <OnIdiom.Phone>
                                <OnPlatform x:TypeArguments = "x:Double" iOS = "30"/>
                            </OnIdiom.Phone>
                            <OnIdiom.Tablet>
                                <OnPlatform x:TypeArguments = "x:Double" iOS = "40"/>
                            </OnIdiom.Tablet>
                        </OnIdiom>
                    </Setter.Value>
                </Setter>
                <Setter Property = "VerticalOptions" Value = "Center"/>
            </Style>
        </ResourceDictionary>
    </Application.Resources>
</Application>

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

Что я пробовал

В другой попытке я сделал Я нашел конвертер и попытался адаптировать его к моему варианту использования. Хотя ошибок intellisense или сборки / компиляции нет, приложение вылетает сразу после открытия. Файл .cs для ArithmeticConverter можно найти по ссылке выше.

<?xml version = "1.0" encoding = "utf-8" ?>
<Application xmlns = "http://xamarin.com/schemas/2014/forms"
             xmlns:x = "http://schemas.microsoft.com/winfx/2009/xaml"
             x:Class = "XamarinDesigner.App"
             xmlns:local = "clr-namespace:XamarinDesigner"
             >
    <Application.Resources>
        <local:ArithmeticConverter x:Key = "AScript"/>

        <ResourceDictionary>
            <OnIdiom x:Key = "StandardFontSize" x:TypeArguments = "x:Double"  Tablet = "22" Phone = "18"/>

            <Style x:Key = "MyEntry" TargetType = "Entry">
                <Setter Property = "FontSize" Value = "{DynamicResource StandardFontSize}"/>
                <Setter Property = "HeightRequest" Value = "{Binding Converter = {StaticResource AScript},ConverterParameter=Int32.Parse(20+{DynamicResource StandardFontSize}}"/>
                <Setter Property = "VerticalOptions" Value = "Center"/>
            </Style>

        </ResourceDictionary>
    </Application.Resources>
</Application>

Я не совсем понимаю использование конвертеров, и {Binding} внутри значения в App.xaml тоже для меня в новинку. Глядя на пример, предоставленный с преобразователем, я думаю, что я близко, чтобы быть правильным, и может просто нужно толкнуть в правильном направлении?


Можно ли выполнять эту базовую арифметическую функцию только на App.xaml (или с помощью преобразователя)? Я надеюсь вместить в этот файл как можно больше.

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

Спасибо за ваше время!

Если вы поместите точку останова внутри вашего конвертера, вы увидите, почему он дает сбой ... Во-первых, в отличие от примера, который вы связали, вы ни к чему не привязываетесь, поэтому ваш value в вашем конвертере будет нулевым . Кроме того, регулярное выражение, используемое в примере, скорее всего, вам не подойдет. И да, вы можете без проблем иметь все это внутри App.xaml.

jsanalytics 13.10.2018 11:18

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

jsanalytics 13.10.2018 12:11

Хм, это один из способов, которым я мог бы это сделать, но я думаю, что это немного сложно с моими вариантами использования / намерениями. Я эффективно пытаюсь настроить эквивалент CSS и стараюсь избегать привязки, где могу, поскольку я просматриваю существующее приложение, обновляющее стили (которое в настоящее время не использует словари ресурсов). Многие страницы уже имеют довольно сложные настройки привязки к другим классам и моделям. В любом случае, я поиграю с этой концепцией и посмотрю, что у меня получится! Спасибо за ваш ответ.

Bejasc 15.10.2018 00:49

Я очень жду того, что вы придумаете. Пожалуйста, опубликуйте свое решение, как только оно у вас будет.

jsanalytics 15.10.2018 09:44
Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
5
4
676
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Одна из причин сбоя вашего приложения заключается в том, что Converter находится за пределами ResourceDictionary.

Решение 1

Связывание следует использовать только тогда, когда назначен BindingContext, поэтому вам необходимо назначить его в файле cs.

App.cs:

public App()
{
    InitializeComponent();
    BindingContext = new { EntryHeightRequest = 10 };
    MainPage = ...
}

App.xaml:

<ResourceDictionary>
    <local:ArithmeticConverter x:Key = "AScript"/>
    <OnIdiom x:Key = "StandardFontSize" x:TypeArguments = "x:Double"  Tablet = "22" Phone = "18"/>
    <Style x:Key = "MyEntry" TargetType = "Entry">
        <Setter Property = "FontSize" Value = "{DynamicResource StandardFontSize}" /> 
        <Setter Property = "HeightRequest" Value = "{Binding EntryHeightRequest, Converter = {StaticResource AScript},ConverterParameter = "{StaticResource StandardFontSize}"/>
        <Setter Property = "VerticalOptions" Value = "Center"/>
    </Style>
</ResourceDictionary>

ArithmeticConverter.cs:

public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
    if (value is int constant && parameter is OnIdiom<double> dynamicSize)
        return constant + dynamicSize.GetValue();
    return -1;
}

OnIdiomExtension:

    public static T GetValue<T>(this OnIdiom<T> idiom)
    {
        switch(Device.Idiom)
        {
            case TargetIdiom.Phone:
                return idiom.Phone;

            case TargetIdiom.Desktop:
                return idiom.Desktop;

            case TargetIdiom.Tablet:
                return idiom.Tablet;

            case TargetIdiom.TV:
                return idiom.TV;

            case TargetIdiom.Watch:
                return idiom.Watch;

            default:
                throw new NotSupportedException();
        }
    }

Остерегаться: когда я пытался, BindingContext передается в ResourceDictionary (а этот пост ему противоречит, может быть, они изменились?)

Решение 2

Подобно Решение 1, но вместо установки BindingContext вы можете использовать OnIdiom для HeightRequest со значением по умолчанию.

<Setter Property = "HeightRequest" Value = "{OnIdiom Default=10, Converter = {StaticResource AScript}, ConverterParameter = {StaticResource StandardFontSize}}" />

Даже если конвертер помещен в словарь ресурсов, он все равно выйдет из строя, потому что есть другие, более «серьезные» проблемы, о которых я упоминал в своем комментарии.

jsanalytics 15.10.2018 09:47

Другие вопросы по теме