Reputation: 661
<Style TargetType="TextBox">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate>
<Grid>
<Border BorderBrush="Red" CornerRadius="2" />
<ScrollViewer x:Name="PART_ContentHost" VerticalAlignment="Center" HorizontalAlignment="Center"/>
<Label x:Name="watermarklabel" Height="40" Content="{TemplateBinding Tag}" Foreground="Gray"/>
</Grid>
<ControlTemplate.Triggers>
<MultiDataTrigger>
<MultiDataTrigger.Conditions>
<Condition Value="True">
<Condition.Binding>
<MultiBinding Converter="{StaticResource Multi}">
<!--<Binding Path="Text" ElementName="txt1"/>-->
<Binding RelativeSource="{RelativeSource Mode=TemplatedParent}" Path="Text"/>
</MultiBinding>
</Condition.Binding>
</Condition>
</MultiDataTrigger.Conditions>
<Setter Property="Visibility" TargetName="watermarklabel" Value="Collapsed"/>
</MultiDataTrigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
Here i want to enable/disable the label (which is water mark) upon the condition when the textbox text is empty and not empty. In the multi binding i am trying to access the text property using the TemplatedParent. But it is not hitting convertor when text changed.
When i use the element name to access it everything is fine.
But i want to make generic this one..
How to make this to work?
Thanks in advance..
Upvotes: 2
Views: 569
Reputation: 44076
This is actually surprisingly tricky to get right. There are a dozen different almost-right answers on the internet, but few or no completely correct ones.
The closest I've ever come to getting this to work correctly is to dynamically inject a textblock into the standard textbox's ControlTemplate at runtime based on the conditions that you're evaluating.
Dynamic injection avoids having to re-implement the entire controltemplate and, assuming the control template doesn't transform too much between versions, also avoids the maintenance point of having to create new ControlTemplates every time built-in theming changes.
Injecting an element instead of modifying the existing text element avoids all kinds of problems where users can select/manipulate the watermark text in undesirable ways.
Avoid an overlaying solution: the z-order and clipping issues aren't worth the effort (I once tried to do this with a decorator, not the right call)
Don't forget to verify that Drag/Drop and Copy/Paste operations on the text box work as expected with the watermark.
IIRC, I did it with an attached property so that a watermark didn't require a new control. Rather, it searched the visual tree for the first viable watermark target it could find and applied the watermark there. This let it work in a combobox as well, e.g., without add'l work.
Upvotes: 1