Привязка ресурса к свойству пользовательского элемента управления - PullRequest
2 голосов
/ 07 февраля 2011

Я создаю пользовательскую кнопку, которая обычно показывает слегка блеклый текст и полный текст на MouseOver или MouseDown.Я определил два ресурса в Generic.xaml моего элемента управления, чтобы представлять кисти для этих цветов текста:

<!-- Text Brushes -->
<SolidColorBrush x:Key="NormalTextBrush" Color="Black" />
<SolidColorBrush x:Key="FadedTextBrush" Color="Gray" />

Элемент управления компилируется и прекрасно работает в этой конфигурации.

Но я хочучтобы позволить пользователю элемента управления установить цвет текста, используя свойство Foreground пользовательского элемента управления.Итак, я изменил объявления ресурсов следующим образом:

<!-- Text Brushes -->
<SolidColorBrush x:Key="NormalTextBrush" Color="{Binding Path=Foreground, RelativeSource={RelativeSource TemplatedParent}}" />
<SolidColorBrush x:Key="FadedTextBrush" Color="{Binding Path=Foreground, RelativeSource={RelativeSource TemplatedParent}, Converter={StaticResource ColorConverter}, ConverterParameter='1.2'}" />

Во втором объявлении для преобразования цвета текста используется конвертер значений HSL.

Теперь элемент управления не работает, иЯ получаю следующую ошибку в окне вывода:

System.Windows.Data Error: 2 : Cannot find governing FrameworkElement or FrameworkContentElement for target element. BindingExpression:Path=Foreground; DataItem='TaskButton' (Name='Button1'); target element is 'SolidColorBrush' (HashCode=38118303); target property is 'Color' (type 'Color')
System.Windows.Data Error: 2 : Cannot find governing FrameworkElement or FrameworkContentElement for target element. BindingExpression:Path=Foreground; DataItem=null; target element is 'SolidColorBrush' (HashCode=47449297); target property is 'Color' (type 'Color')

Я не уверен, что говорит Data Error.Может кто-нибудь сказать мне, что происходит и как это исправить?Спасибо за вашу помощь.

Ответы [ 2 ]

4 голосов
/ 07 февраля 2011

RelativeSource TemplatedParent только (IIRC) имеет значение в шаблоне элемента управления и относится к свойству в экземпляре элемента управления, к которому применяется шаблон.

Содержимое UserControl не является шаблоном UserControl.Таким образом, эта привязка не будет рассматривать родителя UserControl как жизнеспособную цель.

Сообщение об ошибке относится к тому факту, что SolidColorBrush не имеет шаблона;он не расширяет System.Windows.Controls.Control, который является базовым типом (большинства) всех шаблонных элементов управления пользовательского интерфейса.См. Control.Template для получения дополнительной информации о шаблонах.

Что вы хотите сделать, это установить относительный источник FindAncestor.

{Binding Foreground, RelativeSource={RelativeSource FindAncestor, AncestorType=UserControl}}

Это будет идти вверхвизуальное (или это логичное?) дерево для поиска первого предка типа UserControl, а затем связывания с открытым свойством с именем Foreground.

Однако это НЕ будет работать, еслиSolidColorBrush определяется как Resource.Ресурсы не являются частью визуального (или логического дерева, или того и другого - все еще неясно), и поэтому привязка RelativeSource не сможет обойти древо дерева.

Вам придется использовать привязку непосредственно на любом элементе управления, для которого вы хотите иметь тот же цвет переднего плана, что и UserControl.

2 голосов
/ 07 февраля 2011

Проблема в том, что вы не можете использовать RelativeSource привязки к элементам, определенным в ресурсах, поскольку они не являются частью визуального или логического дерева.

Чтобы исправить это, вам просто нужно установить эти привязки в местахгде вы устанавливаете ссылки на ваши ресурсы (в шаблоне управления вашей кнопки).Примерно так:

<ControlTemplate TargetType="{x:Type Button}">
   <Border x:Name="brd" 
           TextBlock.Foreground="{Binding Path=Foreground, RelativeSource={RelativeSource TemplatedParent}}">
      ...
   </Border>
   <ControlTemplate.Triggers>
      <Trigger Property="IsMouseOver"
               Value="True">
          <Setter TargetName="brd"
                  Property="TextBlock.Foreground"
                  Value="{Binding Path=Foreground, RelativeSource={RelativeSource TemplatedParent}, Converter={StaticResource ColorConverter}, ConverterParameter='1.2'}"/>
      </Trigger>
   </ControlTemplate.Triggers>
</ControlTemplate>

Другими словами, вам не нужно определять ресурсы - NormalTextBrush и FadedTextBrush.

...