Luke Le
Luke Le

Reputation: 778

How to show text as background in TextBox correctly?

i have a TextBox and a text hint that show as background:

but location of text as background which is not part of the Text of the base TextBox is not correctly. enter image description here xaml:

<Window x:Class="WpfApplication2.MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:v="clr-namespace:WpfApplication2"
    Title="MainWindow" Height="350" Width="525">
<Grid>
    <TextBox HorizontalAlignment="Left" Height="23" Margin="152,19,0,0" TextWrapping="Wrap" VerticalAlignment="Top" Width="120"
             v:Autocomplete.Hint ="abcd"/>


</Grid>

Autocomplete.cs:

namespace WpfApplication2
{
public static class Autocomplete
{
    #region Hint
    public static string GetHint(DependencyObject obj)
    {
        return (string)obj.GetValue(HintProperty);
    }

    public static void SetHint(DependencyObject obj, string value)
    {
        obj.SetValue(HintProperty, value);
    }

    public static readonly DependencyProperty HintProperty =
        DependencyProperty.RegisterAttached("Hint", typeof(string), typeof(Autocomplete), new PropertyMetadata(string.Empty, OnTextBoxBaseFocus));

    private static string hintText = string.Empty;

    private static void OnTextBoxBaseFocus(DependencyObject d, DependencyPropertyChangedEventArgs e)
    {
        TextBoxBase txtBase = (TextBoxBase)d;

        hintText = GetHint(d);
        if (txtBase == null)
            return;

        if ((string)e.NewValue != null && !GetHint(d).Contains(" "))
        {
            txtBase.GotFocus += txtBase_GotFocus;
            txtBase.LostFocus += txtBase_LostFocus;
        }
        else
            txtBase.TextChanged -= OnChanged;
    }

    static void txtBase_GotFocus(object sender, RoutedEventArgs e)
    {
        AutocompleteText(sender);
    }

    static void txtBase_LostFocus(object sender, RoutedEventArgs e)
    {
        TextBoxBase txtBase = (TextBoxBase)sender;
        // Hide Autocomplete hint
        txtBase.Background = null;
    }




    private static void OnChanged(object sender, TextChangedEventArgs e)
    {
        AutocompleteText(sender);
    }

    private static void AutocompleteText(object sender)
    {
        TextBoxBase txtBase = (TextBoxBase)sender;
        if (txtBase != null && txtBase.Focus())
        {
            // Show Autocomplete hint
            var visual = new TextBlock()
            {
                FontStyle = FontStyles.Normal,
                Text = hintText,
                Foreground = Brushes.Gray
            };

            txtBase.Background = new VisualBrush(visual)
            {
                Stretch = Stretch.None,
                AlignmentX = AlignmentX.Left,
                AlignmentY = AlignmentY.Center,
                Transform = new TranslateTransform(3, 0)
            };
        }
        else
        {
            // Hide Autocomplete hint
            txtBase.Background = null;
        }
    }

    #endregion
}
}

i expected: enter image description here

How to show Autocomplete.Hint as expected?.Thanks for help me !

Upvotes: 2

Views: 332

Answers (1)

Bahman_Aries
Bahman_Aries

Reputation: 4808

One way around this is to use a TextBox as your visual instead of TextBlock. This TextBox must have the same BorderThickness and the same Size as the original TextBoxBase. Therefore your AutocompleteText method should change like this:

private static void AutocompleteText(object sender)
{
    TextBoxBase txtBase = (TextBoxBase)sender;
    if (txtBase != null && txtBase.Focus())
    {
        // Show Autocomplete hint
        var visual = new TextBox()
        {
            BorderThickness = txtBase.BorderThickness,
            BorderBrush = Brushes.Transparent,
            Width = txtBase.ActualWidth,
            Height = txtBase.ActualHeight,

            Text = hintText,
            Foreground = Brushes.Gray
        };

        txtBase.Background = new VisualBrush(visual)
        {
            Stretch = Stretch.None,
        };
    }
    else
    {
        // Hide Autocomplete hint
        txtBase.Background = null;
    }
}

Upvotes: 1

Related Questions