I have made a control inherited from TextBox, but I want an optional Label in front of the textBox.
The soure
Printable View
I have made a control inherited from TextBox, but I want an optional Label in front of the textBox.
The soure
I think there's something missing here... But still, you'll want a UserControl, not a class inheriting TextBox.
I have made a control inherited from TextBox with an optional Label in front of the textBox.
The problem is that I can't see the Label in Design Time, but in execution it goes fine.
Please any help will be welcome.
Thanks.
Miquel
The source:
Public Class LabTex
Inherits System.Windows.Forms.TextBox
Private ObjLabel as Label = Nothing
Private sLabel as string = ""
Property Label() as String
Get
return sLabel
End Get
Set(ByVal Value As String)
sLabel = Value
If sLabel = "" Then
If ObjLabel IsNot Nothing Then
ObjLabel = Nothing
End If
else
If ObjLabel Is Nothing Then
ObjLabel = New Label()
if Me.DesignMode then
Me.Controls.Add(Me.ObjLabel)
'else
' Me.Parent.Controls.Add(Me.ObjLabel)
End If
End If
ObjLabel.Text = sLabel
ObjLabel.AutoSize = True
ObjLabel.Top = Me.Top + (Me.Height / 3)
ObjLabel.Left = Me.Left - 2 - ObjLabel.Width
End If
End Set
End Property
Protected Overrides Sub OnHandleCreated(e As EventArgs)
MyBase.OnHandleCreated(e)
If ObjLabel IsNot Nothing Then
if Me.DesignMode then
Me.Controls.Add(Me.ObjLabel)
else
Me.Parent.Controls.Add(Me.ObjLabel)
End If
ObjLabel.Top = Me.Top + (Me.Height / 3)
ObjLabel.Left = Me.Left - 2 - ObjLabel.Width
End If
End Sub
End Class
Thanks.
I pressed Enter-Key before finished.
I Have posted a new Thread.
as NickThissen told you in your duplicate thread you need to use a usercontrol
Thanks, but I want it inherited from a TextBox because I want to have all TextBox Properties and not the default properties of an UserControl.
The code I post works fine in execution, the only fail is that I can't see the label in design.
In design mode what is the text property for the label ?
Duplicate threads merged - please create only one thread for each question.
In Design I put a value for the property "Label" in te Properties-Editor such as "Code".
In execution I see first Code and then the TextBox, but in design I only see the TextBox.
As has been suggested, a UserControl is the appropriate option here. If you want your control to have the same members as the TextBox class then add them yourself, e.g.vb.net Code:
Public Class LabelledTextBox Inherits UserControl '... Public Sub AppendText(ByVal text As String) Me.TextBox1.AppendText(text) End Sub '... End Class
You can also expose the entire TextBox (as well as the Label should you need to) via a property. The general rule is not to do this, and simply expose all properties manually (as jmcilhinney showed you in the post above this), but if you need many properties, perhaps it's easier to just expose the TextBox completely.
You can do it using a ReadOnly property that returns the textbox:
In the designer (as well as in code) you can now access the TextBox property, expand it (in the property list) and change its properties directly.Code:Public ReadOnly Property TextBox() As TextBox
Get
Return TextBox1 ' or whatever the name of your textbox is
End Get
End Property
Additionally, you may need to add an attribute so that any changes you make in the designer are saved. I'm not too sure about this, but you can try with and without the attribute to see if it has any effect:
You'll need to import a namespace (System.ComponentModel I think), but VB will help you with that.Code:<DesignerSerializationVisibility(DesignerSerializationVisibility.Content)> _
Public ReadOnly Property TextBox() As TextBox
Get
Return TextBox1 ' or whatever the name of your textbox is
End Get
End Property
Thanks again.
But the main reason I want the component inherited from TextBox is the alignement from the Designer. I want put several LabTextBox aligned from Text-Box Left-Corner, not from Label Left-Corner.
If I make an UserControl With Label and TextBox inside it, the alignement from Designer will be made from left-corner of UserControl, not from TextBox.
The code I sent before, works fine in execution because I can add the label to Me.Parent.Controls.Add(Label), where "Me" is the TextBox. But in Design there is no Parent active for the TextBox.
I Have made also this control in Delphi and it works well both in design & execution.
Do you know how I can put in design a Label with same parent than TextBox?
Thanks
You can use a custom ControlDesigner to control the snap-lines, although that is not a trivial task. I'm sure it's possible to tell the designer to use the TextBox's snap-lines, instead of the snap-lines of the UserControl itself, but I don't know exactly how. There was a thread about this in the C# forum a while back if you want to look for it.
Here, I made you a little test designer:
The code represents a UserControl with a TextBox (named TextBox1) and a Label (named Label1).vb.net Code:
Imports System.Windows.Forms.Design Imports System.Windows.Forms.Design.Behavior Imports System.ComponentModel Imports System.ComponentModel.Design <Designer(GetType(LabelTextBox.LabelTextBoxDesigner))> _ Public Class LabelTextBox Public ReadOnly Property TextBox() As TextBox Get Return TextBox1 End Get End Property Public ReadOnly Property Label() As Label Get Return Label1 End Get End Property Friend Class LabelTextBoxDesigner Inherits ControlDesigner Public Overrides ReadOnly Property SnapLines() As System.Collections.IList Get Dim lines = MyBase.SnapLines ' Get a reference to the UserControl we're designing, so we can get to its TextBox Dim ctrl = DirectCast(Me.Control, LabelTextBox) If ctrl IsNot Nothing Then ' Create the designer for the TextBox, so we can get at its SnapLines Using designer As ControlDesigner = TypeDescriptor.CreateDesigner(ctrl.TextBox, GetType(IDesigner)) designer.Initialize(ctrl.TextBox) ' Find the BaseLine snapline (the one that aligns the TextBoxes by text) For Each line As SnapLine In designer.SnapLines If line.SnapLineType = SnapLineType.Baseline Then ' We found the baseline, now add a new SnapLine with a different offset (adding the Top of the TextBox to the offset of the old baseline) lines.Add(New SnapLine(line.SnapLineType, line.Offset + ctrl.TextBox.Top, line.Filter, line.Priority)) End If Next End Using End If ' Return our modified SnapLines Return lines End Get End Property End Class End Class
The UserControl itself merely exposes the TextBox and Label via properties (so I can get to the TextBox in the designer).
Then there is a nested class (LabelTextBoxDesigner) which is the designer for the LabelTextBox UserControl. It overrides the SnapLines property, and modifies the SnapLines of the UserControl by adding a new baseline SnapLine. This new SnapLine has an offset (where it is snapped... so to speak) equal to the baseline SnapLine of the TextBox on our UserControl, plus the Top of the TextBox, so that it is relative to the UserControl.
Try it out. Add a new UserControl called LabelTextBox to your project and drag a Label and a TextBox to it (doesn't matter where they are). Copy/paste my code (quote my post and copy/paste from there to get rid of line-numbers). You'll probably get a lot of errors. If you do, you need to add a reference to System.Design (rightclick the project node in the solution explorer, choose Add Reference, scroll to System.Design and click OK).
Finally, you can build the project, drop a LabelTextBox to your form, as well as a regular TextBox. Now you can align the LabelTextBox to the TextBox using the baseline snaplines of the two TextBox, instead of that of the UserControl:
http://i45.tinypic.com/2myvy9f.png
Cool huh :)
Now, you can use the correct method of using a UserControl, and still align it by the TextBox on the UserControl instead of the UserControl being seen as one large control.
Many thanks NickThissen. I'm grateful for you support and Work.
I tryed your code and it works fine.
I also added Vertical alignement adding a newline after your number 40
lines.Add(new SnapLine(SnapLineType.Left, ctrl.TextBox.Left))
As an example my demo form of LabelTexBox looks as
The LabelTextBox_TextChanged Event not working.
I have tried by handling this event but with no success, Can you code a functionnal TextChanged event if it's possible.
Thanks a lot
It is working. It just doesn't do what you want, so you have to put some thought into what it is that you actually want. The TextChanged event of the LabelTextBox is raised when the Text property of the LabelTextBox changes. You don't care about that. What you care about is the Text property of the child TextBox, so you need to handle the TextChanged event of that child TextBox. You have two choices:
1. You can handle that event directly in the form, which would require you to access the TextBox via the property that Nick provided. This would have to be done in code, using AddHandler to attach the event, which would also require using RemoveHandler to detach the event when you're done with it.
2. Handle the child control's event internally, then raise your own even in the LabelTextBox. That would enable you to then handle that event in the form at design time.
If you want to go with option 1, you should do some reading on AddHandler and try to do it, then post back if you encounter an issue. If you want to go with option 2, you already know how to handle the child event in the LabelTextBox - it's just like any other event - and you can learn how to define and raise your own events here. Again, do what you can for yourself and then post back if you have issues.
Sorry jmcilhinney i haven't succeed even after reading the link you post.
That's why I create a new Thread : https://www.vbforums.com/showthread....Box-with-Label.
Thanks for your help.