У меня есть простой элемент управления, который расширяет элемент управления WPF TextBox
. Основная идея состоит в том, чтобы сэкономить место в пользовательском интерфейсе, позволяя TextBox
отображать свою собственную метку внутри него, когда он пуст.
Я объявил в нем один DependencyProperty
с именем Label
и установил для свойства TextBox.Template
значение ControlTemplate
. ControlTemplate
— это XAML Windows Aero по умолчанию с добавлением TextBlock
, расположенного за элементом управления, который отображает значение свойства TextBox.Text
. Его свойство Visibility
связано с Converter
, чтобы быть видимым, когда свойство Text
пусто. (Там много и в основном неинтересно, так что извините за полосу прокрутки).
<ControlTemplate x:Key="LabelTextBoxTemplate" TargetType="{x:Type TextBoxBase}" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:s="clr-namespace:System;assembly=mscorlib" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:Aero="clr-namespace:Microsoft.Windows.Themes;assembly=PresentationFramework.Aero">
<Aero:ListBoxChrome Background="{TemplateBinding Panel.Background}" BorderBrush="{TemplateBinding Border.BorderBrush}" BorderThickness="{TemplateBinding Border.BorderThickness}" RenderMouseOver="{TemplateBinding UIElement.IsMouseOver}" RenderFocused="{TemplateBinding UIElement.IsKeyboardFocusWithin}" Name="Border" SnapsToDevicePixels="True">
<Grid>
<TextBlock Text="{Binding Label, ElementName=This}" Visibility="{Binding Text, ElementName=This, Converter={StaticResource StringToVisibilityConverter}}" SnapsToDevicePixels="{TemplateBinding UIElement.SnapsToDevicePixels}" FontWeight="Normal" FontStyle="Italic" Foreground="#99000000" Padding="3,0,0,0" />
<ScrollViewer Name="PART_ContentHost" SnapsToDevicePixels="{TemplateBinding UIElement.SnapsToDevicePixels}" />
</Grid>
</Aero:ListBoxChrome>
<ControlTemplate.Triggers>
<Trigger Property="UIElement.IsEnabled" Value="False">
<Setter TargetName="Border" Property="Panel.Background" Value="{DynamicResource {x:Static SystemColors.ControlBrushKey}}" />
<Setter Property="TextElement.Foreground" Value="{DynamicResource {x:Static SystemColors.GrayTextBrushKey}}" />
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
(Свойство Name
элемента управления имеет значение This
для привязки)
Так или иначе, все это прекрасно работает, но мне было интересно, могу ли я заменить эту функциональность прикрепленным свойством. Я создал прикрепленное свойство с именем Label
и добавил делегат обратного вызова, который вызывается при установке свойства. В этом методе я планировал найти ControlTemplate
из Application.Resources
и установить для него свойство TextBox.Template
... Я не смог найти способ получить доступ к ControlTemplate
, так что это мой первый вопрос.
Как я могу получить доступ к ControlTemplate
в Application.Resources
в App.xaml из прикрепленного свойства?
Остальная часть вопроса заключается в том, как я могу привязать к прикрепленному свойству в «ControlTemplate»?
Я пробовал несколько вещей, таких как
Text="{Binding Path=(Attached:TextBoxProperties.Label),
Source={x:Static Attached:TextBoxProperties}, FallbackValue=''}"
но класс TextBoxProperties
, содержащий присоединенное свойство, не является статическим.
ОБНОВЛЕНИЕ >>>
Благодаря Х.Б. Я обнаружил, что могу получить доступ к ControlTemplate
, используя следующий код.
ControlTemplate labelControlTemplate =
(ControlTemplate)Application.Current.FindResource("LabelTextBoxTemplate");