Click here to Skip to main content
13,150,867 members (40,886 online)
Rate this:
 
Please Sign up or sign in to vote.
See more:
Hello,

I created a class :

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


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


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 11-Jun-11 22:26pm
Updated 11-Jun-11 23:32pm
v2
Rate this: bad
 
good
Please Sign up or sign in to vote.

Solution 1

How about using an Adorner to give the underline effect.

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

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
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:

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. :)
  Permalink  
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! :)
Rate this: bad
 
good
Please Sign up or sign in to vote.

Solution 2

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:

<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>
  Permalink  
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.
Tarun.K.S 12-Jun-11 15:30pm
   
Have a 5 for the solution. :)
nit_singh 12-Jun-11 15:42pm
   
Yes Tarun, this is the limitation that you can't assign diff border color for the same controls.

Thanks for your 5 and your quick response...:)
Tarun.K.S 12-Jun-11 15:45pm
   
How about my solution?
nit_singh 12-Jun-11 16:03pm
   
Yes your solution is better but I think if these "CSS type effect" we can achieve by styling then what is the need to touch Codebehind.
Tarun.K.S 12-Jun-11 16:09pm
   
Well even I prefer to use XAML, but I wasn´t getting the required effect, so I had to use Adorner. Thank you.
Shahin Khorshidnia 12-Jun-11 9:03am
   
By the way: Thank you nit-singh

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

  Print Answers RSS
Top Experts
Last 24hrsThis month


Advertise | Privacy |
Web02 | 2.8.170924.2 | Last Updated 12 Jun 2011
Copyright © CodeProject, 1999-2017
All Rights Reserved. Terms of Service
Layout: fixed | fluid

CodeProject, 503-250 Ferrand Drive Toronto Ontario, M3C 3G8 Canada +1 416-849-8900 x 100