Скомпилированные привязки
Привязки, определенные в XAML, используют рефлексию, чтобы найти и получить доступ к запрошенному свойству в вашей ViewModel
. В Avalonia вы также можете использовать скомпилированные привязки, что имеет некоторые преимущества:
- Если вы используете скомпилированные привязки, а свойство, к которому вы привязываетесь, не найдено, вы получите ошибку времени компиляции. Следовательно, вы получаете гораздо лучший опыт отладки.
- Известно, что рефлексия работает медленно (см. эту статью на codeproject.com). Таким образом, использование скомпилированных привязок может повысить производительность вашего приложения.
Включить и отключить скомпилированные привязки
Скомпилированные привязки не включены по умолчанию. Чтобы включить скомпилированные привязки, вам нужно сначала определить DataType
объекта, к которому вы хотите привязаться. В DataTemplates есть свойство DataType
, для всех остальных элементов его можно установить через x:DataType
. Скорее всего, вы установите x:DataType
в своем корневом узле, например, в окне или пользовательском элементе управления. Начиная с версии Avalonia 0.10.12
, вы также можете напрямую указать тип данных в привязке.
Теперь вы можете включить или отключить скомпилированные привязки, установив x:CompileBindings="[True|False]"
. Все дочерние узлы наследуют это свойство, поэтому вы можете включить его в своем корневом узле и отключить для определенного дочернего узла, если это необходимо.
<!-- Set DataType and enable compiled bindings --> <UserControl xmlns="https://github.com/avaloniaui" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:vm="using:MyApp.ViewModels" x:DataType="vm:MyViewModel" x:CompileBindings="True"> <StackPanel> <TextBlock Text="Last name:" /> <TextBox Text="{Binding LastName}" /> <TextBlock Text="Given name:" /> <TextBox Text="{Binding GivenName}" /> <TextBlock Text="E-Mail:" /> <!-- Set DataType inside the Binding-markup --> <TextBox Text="{Binding MailAddress, DataType={x:Type vm:MyViewModel}}" /> <!-- We cannot use compiled bindings to bind to methods, so we opt them out for the button --> <Button x:CompileBindings="False" Content="Send an E-Mail" Command="{Binding SendEmailCommand}" /> </StackPanel> </UserControl>
Разметка CompiledBinding
Если вы не хотите включать скомпилированные привязки для всех дочерних узлов, вы также можете использовать разметку CompiledBinding
. Вам по-прежнему необходимо определить DataType
, но вы можете опустить x:CompileBindings="True"
.
<!-- Set DataType --> <UserControl xmlns="https://github.com/avaloniaui" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:vm="using:MyApp.ViewModels" x:DataType="vm:MyViewModel"> <StackPanel> <TextBlock Text="Last name:" /> <!-- use CompiledBinding markup for your binding --> <TextBox Text="{CompiledBinding LastName}" /> <TextBlock Text="Given name:" /> <TextBox Text="{CompiledBinding GivenName}" /> <TextBlock Text="E-Mail:" /> <TextBox Text="{CompiledBinding MailAddress}" /> <!-- We cannot use compiled bindings to bind to methods, so we use the normal Binding --> <Button Content="Send an E-Mail" Command="{Binding SendEmailCommand}" /> </StackPanel> </UserControl>
Разметка ReflectionBinding
Если вы включили скомпилированные привязки в корневом узле (через x:CompileBindings="True"
) и либо не хотите использовать скомпилированную привязку в определенной позиции, либо столкнулись с одним из известных ограничений, вы можете использовать разметку ReflectionBinding
.
<!-- Set DataType --> <UserControl xmlns="https://github.com/avaloniaui" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:vm="using:MyApp.ViewModels" x:DataType="vm:MyViewModel" x:CompileBindings="True"> <StackPanel> <TextBlock Text="Last name:" /> <TextBox Text="{Binding LastName}" /> <TextBlock Text="Given name:" /> <TextBox Text="{Binding GivenName}" /> <TextBlock Text="E-Mail:" /> <TextBox Text="{Binding MailAddress}" /> <!-- We cannot use compiled bindings to bind to methods, so we use ReflectionBinding instead --> <Button Content="Send an E-Mail" Command="{ReflectionBinding SendEmailCommand}" /> </StackPanel> </UserControl>
Известные ограничения
Скомпилированные привязки имеют некоторые известные ограничения:
- Скомпилированные привязки нельзя использовать для привязки к именованным элементам.
- Скомпилированные привязки нельзя использовать в стилях с RelativeSource, для которого установлено значение TemplatedParent (например:
{Binding Width, RelativeSource={RelativeSource TemplatedParent}}
)
Если вы столкнулись с одним из этих ограничений, вам следует отключить скомпилированные привязки для отказавшего узла XAML или вместо этого использовать ReflectionBinding
.