Новые возможности x:Bind в UWP
Кроме расширений и множества других вещей, в Anniversary Update сильно расширили возможности компилируемых привязок (x: Bind). Давайте посмотрим, что изменилось.
Звездочкой (*) будут помечены возможности, требующие нового SDK.
Коллекции
Теперь вы можете использовать синтаксис вида {x:Bind Collection[0]}
, чтобы привязываться к определенным элементам списка. Более того, если исходный список реализует INotifyCollectionChanged, а Mode установлен в OneWay или TwoWay, привязка будет обновляться при изменении списка (даже если изменение не затрагивает привязанный элемент). Для использования этой возможности список должен реализовывать IList
или IVector
.
Такой синтаксис доступен не только для списков, но также для словарей и Map’ов — {x:Bind Dictionary['Key']}
. Правда типом ключа может быть только string. Аналогично спискам, словарь или Map может реализовывать IObservableMap для обновления привязок. Для экранирования кавычек в строке используется символ ^.
Attached Properties
Появилась возможность привязываться к значениям Attached Properties. Например, {x:Bind MyButton.(Grid.Row)}
привяжется к номеру строки, в которой находится MyButton. Если Attached Property не объявлена в стандартном пространстве имен, вам нужно добавить соответствующий префикс с указанием нужного namespace.
Преобразования*
В отличие от классического Binding, x: Bind строго типизирован, и невалидные привязки выдают ошибки в compile-time. Но бывает так, что вы привязываетесь к свойству с каким-то объявленным типом, но само свойство является объектом более конкретного типа. И даже если вы уверены, что член, которого нет в базовом типе, есть в его наследнике, просто так привязаться к этому члену вы не сможете. Для решения этой проблемы в 1607 добавили возможность кастинга — {x:Bind ((MyObject) Property).Member}
или {x:Bind Property.(MyObject.Member)}
(рекомендуется первый вариант). Это также бывает полезно для преобразования nullable в обычный тип (например, bool? → bool).
BooleanToVisiblityConverter*
Теперь не нужен. Булевые значения будут неявно конвертироваться в Visibility. Наконец-то.
Привязка к функциям*
Это, пожалуй, самая мощная новая возможность x: Bind. Теперь вы можете привязываться непосредственно к возвращаемым значениям функций. Например, {x:Bind MyNumber.ToString('F4')}
будет возвращать MyNumber с 4 знаками после запятой.
- В качестве аргументов вы можете передавать числа, строки, булевые значения (x: True и x: False), null (x: Nul) и пути к вашим свойствам. К тому же, если Mode установлен в OneWay или TwoWay, привязка будет обновляться при изменении аргументов.
- Вы можете привязываться и к статическим методам, используя нотацию
пространствоимен:Класс.Метод
. - Для использования TwoWay-привязки вам потребуется указать BindBack. Эта функция будет вызываться при изменении значения в пользовательском интерфейсе, и она должна принимать один аргумент (новое значение). Пример —
{x:Bind MyFunction(MyProperty), BindBack=Update}
Разумеется, есть ограничения:
- Функция должна быть доступна в месте вызова
- Перегрузка выполняется по количеству, а не типам аргументов. То есть, выбрана будет первая функция, имеющая подходящее количество аргументов.
- Передаваемые типы должны точно совпадать с принимаемыми.
- Возвращаемый тип должен точно совпадать с значением свойства, к которому идет привязка.
Как мы видим, XAML, хоть и неспешно, но развивается, что очень радует. Вполне возможно, что в RS2 и RS3 тоже добавят что-нибудь новое. А пока можно потихоньку осваивать новые вещи и избавляться от ненужного теперь кода.