Silverlight Watermarked AutoComplete Box
-
13-09-2019 - |
Question
Can someone direct me to an example or explanation that will help me either:
- Extend the SilverLight AutoComplete Box to allow watermarks.
- Extend the Watermark TextBox to allow AutoComplete functionality.
It strikes me that option 1 would be easiest, but I'm open.
Thanks in advance.
Solution
Right off the bat, I'd say option 1 is good:
1) Create an attached property to hold the WatermarkText that you can use on AutoCompleteBox.
2) Create a control template for the AutoCompleteBox (simply copy the existing one using blend), but change the TextBox to a Watermark TextBox, and use a TemplateBinding to set the WatermarkTextBox's property to the value of the attached property. The control template should be applied in a style (for example WatermarkedAutoCompleteBoxStyle).
You should be good to go with that. Any time you want a watermarked autocomplete box, just set the attached property value and apply the style you defined.
If you need more in-depth explanation of one of those steps, just raise your hand and I'll try to find the time to create a sample.
Alternatively you can derive from AutoCompleteBox, add a DependencyProperty instead of an attached property and package the style in the Themes/generic.xaml file, but I usually do it once it works.
OTHER TIPS
Based on Steve's answer:
Public Class WatermarkExtender
Inherits DependencyObject
Public Shared ReadOnly WatermarkProperty As DependencyProperty =
DependencyProperty.RegisterAttached(
"Watermark",
GetType(Object),
GetType(WatermarkExtender),
New UIPropertyMetadata(Nothing))
Public Shared ReadOnly WatermarkTemplateProperty As DependencyProperty =
DependencyProperty.RegisterAttached(
"WatermarkTemplate",
GetType(DataTemplate),
GetType(WatermarkExtender),
New UIPropertyMetadata(Nothing))
Public Shared Sub SetWatermark(ByVal element As UIElement, ByVal value As Object)
element.SetValue(WatermarkProperty, value)
End Sub
Public Shared Function GetWatermark(ByVal element As UIElement) As Object
Return element.GetValue(WatermarkProperty)
End Function
Public Shared Sub SetWatermarkTemplate(ByVal element As UIElement, ByVal value As Object)
element.SetValue(WatermarkTemplateProperty, value)
End Sub
Public Shared Function GetWatermarkTemplate(ByVal element As UIElement) As Object
Return element.GetValue(WatermarkTemplateProperty)
End Function
End Class
The style:
<!-- input:AutoCompleteBox -->
<Style TargetType="input:AutoCompleteBox">
...
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="input:AutoCompleteBox">
<Grid Opacity="{TemplateBinding Opacity}">
<extk:WatermarkTextBox
Padding="{TemplateBinding Padding}"
Background="{TemplateBinding Background}"
IsTabStop="True"
x:Name="Text"
Style="{TemplateBinding TextBoxStyle}"
BorderThickness="{TemplateBinding BorderThickness}"
BorderBrush="{TemplateBinding BorderBrush}"
Foreground="{TemplateBinding Foreground}"
Margin="0"
Watermark="{Binding Path=(local:WatermarkExtender.Watermark), Mode=TwoWay, RelativeSource={RelativeSource TemplatedParent}}"
WatermarkTemplate="{Binding Path=(local:WatermarkExtender.WatermarkTemplate), Mode=TwoWay, RelativeSource={RelativeSource TemplatedParent}}" />
...
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
Usage:
<Window.Resources>
<Style x:Key="acWatermarkStyle" TargetType="{x:Type wtk:AutoCompleteBox}" BasedOn="{StaticResource {x:Type wtk:AutoCompleteBox}}">
<Setter Property="local:WatermarkExtender.WatermarkTemplate">
<Setter.Value>
<DataTemplate>
<TextBlock Foreground="Gray" Margin="3,0,0,0" Text="{Binding}" />
</DataTemplate>
</Setter.Value>
</Setter>
</Style>
</Window.Resources>
<wtk:AutoCompleteBox
Height="25"
Margin="2"
Style="{StaticResource acWatermarkStyle}"
HorizontalAlignment="Stretch"
ValueMemberPath="SomeProp"
FilterMode="Custom"
local:WatermarkExtender.Watermark="type something" />