2

I want to create custom text box (which will contain simple watermark/hint text) and I some reached problems with dependecy properties. My custom class inherits from TextBox class and consist of two files (.xaml .cs) C# code file is very simple:

public partial class HintTextBox : TextBox
{
    public string HintText
    {
        get { return (string)GetValue(HintTextProperty); }
        set { SetValue(HintTextProperty, value); }
    }
    public static readonly DependencyProperty HintTextProperty =
        DependencyProperty.Register(
            "HintText",
            typeof(string),
            typeof(HintTextBox),
            new FrameworkPropertyMetadata(string.Empty));
}

.xaml file contains code which show/hide watermark

<local:HintTextBox xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
                xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
                xmlns:local="clr-namespace:Ribes.Client.GUI"
                xmlns:sys="clr-namespace:System;assembly=mscorlib">
<local:HintTextBox.Style>
    <Style TargetType="{x:Type local:HintTextBox}">
        <Style.Resources>
            <VisualBrush x:Key="CueBannerBrush" AlignmentX="Left" AlignmentY="Center" Stretch="None">
                <VisualBrush.Visual>
                    <Label Content="{Binding HintText, ElementName=local:HintTextBox}" Foreground="LightGray" />
                </VisualBrush.Visual>
            </VisualBrush>
        </Style.Resources>
        <Style.Triggers><!-- triggers changing content of control --></Style.Triggers>
    </Style>
</local:HintTextBox.Style>

I'm trying to obtain simple usage of my HintTextBox:

<local:HintTextBox HintText="hint text"></local:HintTextBox>

And it's does not work. After create brakepoint on line :

SetValue(HintTextProperty, value);

code is never reached. Inherited properties (Text,Background) of TextBox works fine:

<local:HintTextBox Text="example text" Background="Yellow"></local:HintTextBox>

We can see correct yellow TextBox with 'example text' inside.

Have anybody idea what can be wrong with my DP ?

Regars NQ

NeuroXiq
  • 23
  • 1
  • 6
  • 1
    Refer my answer here http://stackoverflow.com/questions/37995806/textpreview-for-textbox/37997102#37997102 – Ayyappan Subramanian Aug 31 '16 at 14:45
  • 1
    if i remember correct, WPF doesn't use wrapper properties for DP, it uses `SetValue` with DP - that is why breakpoint is not reached. i suspect, that binding (`{Binding HintText, ElementName=local:HintTextBox}`) is incorrect (i mean `ElementName`) – ASh Aug 31 '16 at 14:50

3 Answers3

1

You will want to use Generic.xaml to style your textbox. To do this you will need to override the DefaultStyleKey in a static constructor.

HintTextBox.cs

public class HintTextBox : TextBox
{
    public static DependencyProperty HintTextProperty = DependencyProperty.Register("HintText", typeof(string), typeof(HintTextBox));

    public string HintText
    {
        get { return (string)GetValue(HintTextProperty); }
        set { SetValue(HintTextProperty, value); }
    }

    static HintTextBox()
    {
        DefaultStyleKeyProperty.OverrideMetadata(typeof(HintTextBox), new FrameworkPropertyMetadata(typeof(HintTextBox)));
    }
}

Generic.xaml

<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
                    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
                    xmlns:Local="Ribes.Client.GUI">

    <!-- Describes how to style a HintTextBox -->
    <Style x:Key="{x:Type Local:HintTextBox}" BasedOn="{StaticResource {x:Type TextBox}}" TargetType="{x:Type Local:HintTextBox}">
        <Setter Property="Template">
            <Setter.Value>
                <ControlTemplate TargetType="{x:Type Local:HintTextBox}">
                    <Border x:Name="Border" Background="{TemplateBinding Background}" BorderBrush="{TemplateBinding BorderBrush}"
                            BorderThickness="{TemplateBinding BorderThickness}" SnapsToDevicePixels="True">
                        <Grid x:Name="LayoutGrid">
                            <ScrollViewer x:Name="PART_ContentHost" Margin="2" />
                            <Label x:Name="HintText" Content="{Binding HintText, RelativeSource={RelativeSource TemplatedParent}}"
                                   FontStyle="Italic" Margin="2" Padding="2,0,0,0" />
                        </Grid>
                    </Border>
                    <ControlTemplate.Triggers>
                        <Trigger Property="HasText" Value="True">
                            <Setter Property="Visibility" TargetName="HintText" Value="Hidden" />
                        </Trigger>
                    </ControlTemplate.Triggers>
                </ControlTemplate>
            </Setter.Value>
        </Setter>
    </Style>
</ResourceDictionary>
Derrick Moeller
  • 4,808
  • 2
  • 22
  • 48
0

try this and set a break point :

public string HintText
    {
        get { return (string)GetValue(HintTextProperty); }
        set { SetValue(HintTextProperty, value); }
    }
    public static readonly DependencyProperty HintTextProperty =
        DependencyProperty.Register(
            "HintText",
            typeof(string),
            typeof(HintTextBox),
            new FrameworkPropertyMetadata(null,FrameworkPropertyMetadataOptions.BindsTwoWayByDefault,(sender,e)=>{

                //Set Break Point Here

            });
  • I think it's a bit unfortunate... you give a hint, how a change in the DP could be monitored, but you don't describe, why your solution is better than the question code. And I have a feeling, that the question *"Have anybody idea what can be wrong with my DP?"* actually does'nt just target the DP store value but also the visual representation of the `HintText`, even though this is not explicitely asked. – grek40 Aug 31 '16 at 17:57
-1

I don't have any access to Visual Studio right now but I think you might need to replace FrameworkPropertyMetadata with UIPropertyMetadata into your DependencyProperty.

Amaury Levé
  • 1,459
  • 10
  • 21