Question

Can someone direct me to an example or explanation that will help me either:

  1. Extend the SilverLight AutoComplete Box to allow watermarks.
  2. Extend the Watermark TextBox to allow AutoComplete functionality.

It strikes me that option 1 would be easiest, but I'm open.

Thanks in advance.

Was it helpful?

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" />
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top