Как работает отрисовка в фреймворках на основе XAML

Моя цель - предложение широкого ассортимента товаров и услуг на постоянно высоком качестве обслуживания по самым выгодным ценам.

Довольно часто мне приходится видеть вопросы, причиной которого либо непонимание как работают под капотом фреймоворки на базе XAML (я работал с WPF и AvaloniaUI, но имею все основания считать, что эта информация применима и к другим их родственникам).

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

Давайте начнём с одного простого примера, а потом будем развивать мысль дальше:

<Button>Hello world</Button>

<Button>
  <StackPanel Orientation="Horizontal">
    <Image Source="/Assets/Help.png" />
    <AccessText>_Help</AccessText>
  </StackPanel>
</Button>
Как это выглядит
Как это выглядит

Здесь две кнопки, на одной просто текст, на другой - некоторое содержимое, содержащее элементы самого фреймворка. И то и другое работает как ожидается, но по сути здесь работает два разных механизма (на самом деле всё ещё интереснее, но и до этого доберёмся).

Хочу сразу обратить внимание на один важный момент: свойство Content у кнопки, унаследованный от ContentControl имеет тип object - это важно для дальнейшего повествования.

Давайте попробуем объяснить текущее поведение: если содержимое - строка, то она отображается как текст. Если содержимое - часть фреймворка, то оно знает как себя рисовать, и поэтому отрисовка ему и делегируется. Но могут быть и иные варианты, верно?

Сделаем простенькую ViewModel со свойством некоторого нашего типа и попробуем его расположить в кнопке:

public class MainViewModel
{
    public ButtonContent ButtonContent { get; } = new() { Action = "Do something" };
}

public class ButtonContent
{
    public required string Action { get; init; }
}
<Button Content="{Binding ButtonContent}" />

И что же мы видим?

Видим вызванный ToString
Видим вызванный ToString

Попробуем добавить шаблон данных:

<Button Content="{Binding ButtonContent}" >
  <Button.DataTemplates>
    <DataTemplate DataType="vm:ButtonContent">
      <TextBlock Text="{Binding Action}" FontWeight="Bold" />
    </DataTemplate>
  </Button.DataTemplates>
</Button>
Шаблон работает
Шаблон работает

А что, если мы сделаем шаблон для строки?

<Button Content="Hello world" >
  <Button.DataTemplates>
    <DataTemplate DataType="system:String">
      <TextBlock>
        <Run Text="“" />
        <Run Text="{Binding }" TextDecorations="Underline" />
      </TextBlock>
    </DataTemplate>
  </Button.DataTemplates>
</Button>
Забавно, но это тоже работает!
Забавно, но это тоже работает!

Итак, выводим общее правило:

  1. если объект является частью фреймворка, то он сам себя отрисовывает

  2. в противном случае для него ведётся поиск шаблона, и если он найден, то для отрисовки используется этот шаблон

  3. если подходящего шаблона не нашлось, то на объекте вызывается ToString, он заворачивается в текстовый элемент (TextBlock или AccessText), и уже он рисуется.

Ну и для полноты картины: если речь про списочный элемент, то аналогичные правила применяются для каждого элемента списка.

Как понять, когда такие правила применимы? Очень просто: если свойство, отвечающее за содержимое, имеет тип object, или есть коллекция объектов, или коллекция не generic, то почти наверняка это правило работает.


Работаете с графическими фреймворками и всё ещё не присоединились к чату в телеграме? Надо срочно исправить эту недоработку: https://t.me/AvaloniaRU

Только зарегистрированные пользователи могут участвовать в опросе. Войдите, пожалуйста.
Используете ли Вы фреймвоки, основанные на XAML?
60% Да, регулярно3
20% Иногда1
0% Нет, просто любопытствую0
20% Нет1
Проголосовали 5 пользователей. Воздержавшихся нет.
Источник: https://habr.com/ru/articles/821795/


Интересные статьи

Интересные статьи

Всем привет! Меня зовут Алина Акиншина, я генеральный директор IT-компании Онлайн Патент. Мы ведем блог здесь, на Хабре, и сегодня решили написать в нем про наш собственный опыт —о том, как мы прожили...
"Нас более 150 человек из более 15 стран и 70 разных городов мира и все мы стали жертвами новой схемы кибермошенников, которые под видом инвестиций на липовых брокерских биржах убедили нас перевести п...
Безопасность важна. Никто не хочет выступать против безопасности. Поэтому все замалчивают проблему с npm audit. Но кто-то должен сказать. Думаю, придётся мне. npm audit работает при...
Почта Mail.ru — наш самый известный продукт и ценнейший актив — к 2020 году сильно вырос. Сегодня это больше, чем просто почтовый сервис: в Почте можно отправлять и получать письм...
Привет! Меня зовут Антон Даценко и я отвечаю за развитие корпоративных решений и сервисов в подразделении Билайн Бизнес. Сегодня я расскажу вам, как мы используем технологии резервирования и б...