HimorriveL
HimorriveL

Reputation: 21

cursor keyboard not showing on textbox

I have a "geric "styleTextBox with Watermark, its working but, when I request a Focus for this textbox by command line (textbox.focus();) he have a background yellow but the cursor keyboard dont display, but I can change text value, What I doing wrong to dont display this cursor?

<Style x:Key="StyledTextBox" TargetType="{x:Type TextBox}" BasedOn="{StaticResource baseStyle}">
        <Setter Property="BorderBrush" Value="Black" />
        <Setter Property="BorderThickness" Value="1" />
        <Setter Property="Template">
            <Setter.Value>
                <ControlTemplate TargetType="{x:Type TextBox}">
                    <Border x:Name="bg" Background="{TemplateBinding Background}" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}"
                            FocusManager.FocusedElement="{Binding ElementName=inputText}">
                        <Grid>
                            <TextBlock Text="{TemplateBinding Tag}" VerticalAlignment="Center" Margin="8,0,0,0">
                                <TextBlock.Visibility>
                                    <MultiBinding Converter="{StaticResource InputToVisibility}">
                                        <Binding ElementName="inputText" Path="Text.IsEmpty" />
                                        <Binding ElementName="inputText" Path="IsFocused" />
                                    </MultiBinding>
                                </TextBlock.Visibility>
                            </TextBlock>
                            <TextBox Name="inputText" Background="Transparent" BorderThickness="0"
                                    Text="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=Text, UpdateSourceTrigger=PropertyChanged}"
                                    VerticalContentAlignment="{TemplateBinding VerticalContentAlignment}" HorizontalContentAlignment="{TemplateBinding HorizontalContentAlignment}"
                                     />
                        </Grid>
                    </Border>
                    <ControlTemplate.Triggers>
                        <Trigger Property=" IsFocused" Value=" true">
                            <Setter TargetName="bg" Property="BorderThickness" Value="5" />
                            <Setter TargetName="bg" Property="Background" Value="Yellow" />
                        </Trigger>
                        <Trigger Property="IsFocused" Value="false">
                            <Setter Property="Background" TargetName="bg" Value="red" />
                        </Trigger>
                    </ControlTemplate.Triggers>

                </ControlTemplate>
            </Setter.Value>
        </Setter>
    </Style>

Upvotes: 0

Views: 66

Answers (1)

Keithernet
Keithernet

Reputation: 2509

The root of your problem is that you're putting a TextBox inside your TextBox control template and trying to manage the focus. This is a bad approach.

Instead you need to extract the TextBox control template and modify it by adding your watermark element along with some triggers.

Here is a very rough example of what I'm talking about. This XAML is truncated for clarity, but should give you an idea:

If you see ... that's where the other XAML layout and/or triggers go.

    <ControlTemplate x:Key="TextBoxTemplate" TargetType="{x:Type TextBox}">
        <Grid x:Name="RootElement"
            SnapsToDevicePixels="True"
            UseLayoutRounding="True">
                ...            
                <ScrollViewer x:Name="PART_ContentHost"
                    Padding="{TemplateBinding Padding}"
                    HorizontalContentAlignment="{TemplateBinding HorizontalContentAlignment}"
                    VerticalContentAlignment="{TemplateBinding VerticalContentAlignment}"
                    Background="Transparent"
                    BorderThickness="0"
                    Foreground="{TemplateBinding Foreground}" />
                <TextBlock x:Name="WatermarkElement"
                    Margin="{TemplateBinding Padding}"
                    HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}"
                    VerticalAlignment="{TemplateBinding VerticalContentAlignment}"
                    Foreground="{TemplateBinding Foreground}"
                    Opacity="0.5"
                    Text="{Binding Path=Tag, RelativeSource={RelativeSource TemplatedParent}}"
                    Visibility="Collapsed" />
        </Grid>
        <ControlTemplate.Triggers>
            ...
            <MultiDataTrigger>
                <MultiDataTrigger.Conditions>
                    <Condition Binding="{Binding Path=Text, RelativeSource={RelativeSource Self}, Converter={StaticResource StringLengthToBoolConverter}}" Value="false" />
                    <Condition Binding="{Binding Path=Tag, RelativeSource={RelativeSource Self}, Converter={StaticResource StringLengthToBoolConverter}}" Value="true" />
                    <Condition Binding="{Binding RelativeSource={RelativeSource Self}, Path=IsKeyboardFocusWithin}" Value="false" />
                </MultiDataTrigger.Conditions>
                <Setter TargetName="WatermarkElement" Property="Visibility" Value="Visible" />
            </MultiDataTrigger>
        </ControlTemplate.Triggers>
    </ControlTemplate>

My example uses a value converter called StringLengthToBoolConverter which evaluates a string for IsNullOrEmpty and returns true or false.

Upvotes: 0

Related Questions