Вопрос

Что разница между этими двумя привязками:

<ControlTemplate TargetType="{x:Type Button}">
   <Border BorderBrush="{TemplateBinding Property=Background}">
      <ContentPresenter />
   </Border>
</ControlTemplate>

и

<ControlTemplate TargetType="{x:Type Button}">
   <Border BorderBrush="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=Background}">
      <ContentPresenter />
   </Border>
</ControlTemplate>

?

Это было полезно?

Решение

TemplateBinding — это не совсем то же самое.Документы MSDN часто пишутся людьми, которым приходится задавать односложные SDE вопросы о функциях программного обеспечения, поэтому нюансы не совсем верны.

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

Разметка привязки разрешается во время выполнения.Несмотря на то, что привязка выполняется медленнее, она разрешает имена свойств, которые не отображаются в типе, объявленном шаблоном.Говоря медленнее, я отмечу, что это своего рода относительно, поскольку операция привязки занимает очень мало ресурсов процессора приложения.Если бы вы крутили шаблоны управления на высокой скорости, вы могли бы это заметить.

На практике используйте TemplateBinding, когда вы можете, но не боитесь привязки.

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

Привязка шаблона - Больше ограничений, чем при использовании обычной привязки.

  • Более эффективен, чем Binding, но имеет меньшую функциональность.
  • Работает только внутри визуального дерева ControlTemplate.
  • Не работает со свойствами в Freezables.
  • Не работает в триггере ControlTemplate.
  • Предоставляет ярлык для настройки свойств (не такой подробный), например.{TemplateBinding targetProperty}

Обычный Связывание - Не имеет вышеуказанных ограничений TemplateBinding.

  • Уважает родительские свойства
  • Сбрасывает целевые значения, чтобы удалить все явно заданные значения.
  • Пример:<Ellipse Fill="{Binding RelativeSource={RelativeSource TemplatedParent},Path=Background}"/>

Еще одна вещь: TemplateBindings не позволяют конвертировать значения.Они не позволяют вам передавать Converter и, например, не преобразуют автоматически int в строку (что нормально для привязки).

TemplateBinding — это сокращение от Binding с TemplatedParent, но оно не раскрывает все возможности класса Binding, например, вы не можете управлять Binding.Mode из TemplateBinding.

Относительный источник

Этот режим позволяет связать данное свойство ControlTemplate со свойством элемента управления, к которому применяется ControlTemplate.Чтобы лучше понять проблему, вот пример ниже.

<Window.Resources>
    <ControlTemplate x:Key="template">
        <Canvas>
            <Canvas.RenderTransform>
                <RotateTransform Angle="20"/>
            </Canvas.RenderTransform>
            <Ellipse Height="100" Width="150" 
                     Fill="{Binding 
                RelativeSource={RelativeSource TemplatedParent},
                Path=Background}">

            </Ellipse>
            <ContentPresenter Margin="35" 
                      Content="{Binding RelativeSource={RelativeSource  
                      TemplatedParent},Path=Content}"/>
        </Canvas>
    </ControlTemplate>
</Window.Resources>

<Canvas Name="Parent0">
    <Button   Margin="50" 
              Template="{StaticResource template}" Height="0" 
              Canvas.Left="0" Canvas.Top="0" Width="0">
        <TextBlock FontSize="22">Click me</TextBlock>
    </Button>
</Canvas>

Если я хочу применить свойства данного элемента управления к его шаблону элемента управления, я могу использовать режим TemplatedParent.Существует также аналог этого расширения разметки — TemplateBinding, который является своего рода сокращенной версией первого, но TemplateBinding оценивается во время компиляции в отличие от TemplatedParent, который оценивается сразу после первого выполнения.Как вы можете заметить на рисунке ниже, фон и содержимое применяются изнутри кнопки к шаблону элемента управления.

Я думал, что TemplateBinding не поддерживает типы Freezable (включая объекты кисти).Чтобы обойти проблему.Можно использовать TemplatedParent

Они используются аналогичным образом, но имеют несколько отличий.Вот ссылка на документацию TemplateBinding:http://msdn.microsoft.com/en-us/library/ms742882.aspx

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top