Можно ли заменить этот пользовательский элемент управления WPF TextBox присоединенным свойством?

У меня есть простой элемент управления, который расширяет элемент управления 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");

person Sheridan    schedule 04.11.2011    source источник


Ответы (1)


Вы должны иметь доступ к Application.Resources из: Application.Current.Resources.

Привязка, вероятно, должна быть такой:

{Binding (Attached:TextBoxProperties.Label),
         RelativeSource={RelativeSource AncestorType=TextBox}}

Не имеет значения, является ли класс, содержащий свойство, статическим, механизм привязки увидит, установлено ли свойство в TextBox, его не волнует объявляющий класс.

person H.B.    schedule 04.11.2011
comment
Он работает отлично! Спасибо большое. Я не перестаю удивляться тому, что можно создать в WPF, не создавая пользовательских элементов управления! - person Sheridan; 05.11.2011