Click here to Skip to main content
15,885,537 members
Please Sign up or sign in to vote.
4.80/5 (5 votes)
See more:
Hello,

I created a class :

C#
public class ShahinTextBox : System.Windows.Controls.TextBox
    {
...


I want to draw a line below the text box after focusing on this control.


C#
protected override void OnGotFocus(RoutedEventArgs e)
{
DrawingVisual drawingVisual = new DrawingVisual();
DrawingContext drawingContext = drawingVisual.RenderOpen();
Pen pen = new Pen(Brushes.Red ,1);
drawingContext.DrawLine(pen, new Point(0, this.Height), new Point(this.Width, this.Height));
}


No Error, But it doesn't work. I need your help !
Posted
Updated 11-Jun-11 23:32pm
v2

How about using an Adorner to give the underline effect.

It goes like this:
Create a class which inherits Adorner.

C#
class AdornOnTextBox : Adorner
{
        public AdornOnTextBox(UIElement adornedElement):base(adornedElement)
        {

        }

        protected override void OnRender(System.Windows.Media.DrawingContext drawingContext)
        {
            Rect adornedElementRect = new Rect(AdornedElement.RenderSize);
            Pen pen = new Pen(Brushes.Red, 1);
            
            drawingContext.DrawLine(pen, adornedElementRect.BottomLeft, adornedElementRect.BottomRight);
        }
    }


Lets say the name of the UserControl in your WPF app is NewTextBox.

Attach an event handler for GotFocus.
Add the below in the constructor
C#
NewTextBox.GotFocus += new RoutedEventHandler(TextGotFocus);
//In case you want to remove the line if Focus is lost.
NewTextBox.LostFocus += new RoutedEventHandler(TextLostFocus);
AdornOnTextBox adornIt;
AdornerLayer textLayer;


Here are the eventhandlers:

C#
void TextGotFocus(object sender, RoutedEventArgs e)
{
    adornIt = new AdornOnTextBox(NewTextBox);
    textLayer= AdornerLayer.GetAdornerLayer(NewTextBox);
    textLayer.Add(adornIt);
}

//Removes the line if focus is lost
void TextLostFocus(object sender, RoutedEventArgs e)
        {
            textLayer.Remove(adornIt);
        }


Hope this works out. :)
 
Share this answer
 
v2
Comments
Shahin Khorshidnia 12-Jun-11 6:49am    
Hi,
What is "adornt"?

"textLayer.Add(adornt);"
Shahin Khorshidnia 12-Jun-11 6:54am    
Ok, I think you mean: adornIt

Thank you. It works. :)
Tarun.K.S 12-Jun-11 7:46am    
Oops I am sorry for the typo! Glad it helped. :)
nit_singh 12-Jun-11 16:03pm    
my 5 for your better solution
Tarun.K.S 12-Jun-11 16:10pm    
Thank you! :)
Why don't you use the Style for the TextBox

put the below code to App.xaml (Application Resource) file.

<Application.Resources>
        <Style TargetType="TextBox" x:Key="txtStyle">
            <Setter Property="Template">
                <Setter.Value>
                    <ControlTemplate TargetType="TextBox">
                        <Border Name="TextBorder" Margin="2" Height="30" Background="{TemplateBinding Background}"
                                BorderBrush="Aqua" BorderThickness="1">
                            <ScrollViewer x:Name="PART_ContentHost" Focusable="True" />
                        </Border>
                        <ControlTemplate.Triggers>
                            <Trigger Property="IsFocused" Value="True">
                                <Setter TargetName="TextBorder" Property="BorderBrush" Value="Aqua"/>
                                <Setter TargetName="TextBorder" Property="BorderThickness" Value="1,1,1,5"/>
                            </Trigger>
                        </ControlTemplate.Triggers>
                    </ControlTemplate>
                </Setter.Value>
            </Setter>
        </Style>
    </Application.Resources>


Now we can use this style like

<TextBox Name="txtNameTest" Width="200" Style="{StaticResource txtStyle}" ></TextBox>


This piece of code will add a AQUA line below the TextBox when the focus will come to it.

Update by Tarun:

I have updated the ControlTemplate.Triggers part:

XML
<ControlTemplate.Triggers>
    <Trigger Property="IsFocused" Value="True">
        <Setter TargetName="TextBorder" Property="BorderBrush" Value="Red"/>
        <Setter TargetName="TextBorder" Property="BorderThickness" Value="0.3,0.3,0.3,1"/>
    </Trigger>
</ControlTemplate.Triggers>
 
Share this answer
 
v3
Comments
Tarun.K.S 12-Jun-11 8:05am    
I have a doubt. What is the use of ScrollViewer inside the Border? I am definitely missing something here.
nit_singh 12-Jun-11 13:26pm    
Using ScrollViewer you can use Single line textbox as multiline also with applying any other setting.
Tarun.K.S 12-Jun-11 13:35pm    
Aah I knew it, but unfortunately its not working. Is it fine on your side?
nit_singh 12-Jun-11 15:18pm    
Yes Tarun it is working fine on my side. Try again I modified the solution again.
Tarun.K.S 12-Jun-11 15:29pm    
I have updated the Triggers part. But the problem is one cannot give a separate color(here Red) to the bottom borderthickness. Anyway I have given a small effect of border in the textbox by setting the 0.3 to other borderthicknesses.

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900