I cannot acces the choosen properties from new component  
Author Message
clemenslinders





PostPosted: Common Language Runtime, I cannot acces the choosen properties from new component Top

LS,

I'm using VS 2005 C#. I created a new component that inherits form textbox. I added a Label to this textbox.

private Label tBLabel;
[Description("Label above Textbox.")]
public Label TBLabel
{
get { return tBLabel; }
set { tBLabel = value; }
}

private void InitializeTB()
{
tBLabel = new Label();
}


I can use my new component.
In the properties box I can see TBLabel
I can change the properties for TBLabel (for instance change it's Text to: This is a label)

But when I run the program the de**** shows me that textbox1.TBLabel.Text=empty

Probably the problem is that I during initialization I have to state tBLabel = new Label(); If I do not use this line I get an error.

Does anyone know how I can overcome this problem

My guess is that it should be possible.

Kind regards,

Clemens Linders




.NET Development4  
 
 
TaylorMichaelL





PostPosted: Common Language Runtime, I cannot acces the choosen properties from new component Top

The simple solution:

private Label tBLabel = new Label();

[Description("Label above Textbox.")]
public Label TBLabel
{
get { return tBLabel; }
}

For objects that are not often needed or are expense to create use delay initialization:

private Label tBLabel;

public Label TBLabel
{
get
{
if (m_tBLabel == null)
m_tBLabel = new Label();

return m_tBLabel;
}
}

For a control that is fine. For non-controls that need to be thread safe you should use a thread-safe swap like so:

private Label tBLabel;

public Label TBLabel
{
get
{
if (m_tBLabel == null)
Interlocked.CompareExchange(ref m_tBLabel, new Label(), null);

return m_tBLabel;
}
}

In the TS case the if is optional but provides slightly better performance as it short-circuits a method call in the general case.

Michael Taylor - 10/27/06


 
 
nobugz





PostPosted: Common Language Runtime, I cannot acces the choosen properties from new component Top

Turning a TextBox control into a container is probably going to get you into a lot of trouble. Try using a UserControl that hosts both the TextBox and the Label. It was designed to properly manage the lifetime of its constituent controls...


 
 
clemenslinders





PostPosted: Common Language Runtime, I cannot acces the choosen properties from new component Top

Hi Hans and Michael,

Michael I tried your solution but the problem remains. In your second approach you use m_tBLabel but you haven't declared that public/private

Hans, could you be a bit more detailed I guess you want me that my textbox doesn't inherit from TextBox but UserControl, if so does that change my problem about not being able to use the designtime propertie box

I also got some emails that people didn't understand my problem, so before I give you more code I will try to explain what actually is my problem.

It's basically very simple. Start a new WinControl let it inherit from textbox and add a property Label called tBLabel. In the Event BindingContactChanged (which is activated when the textbox is drawn for the first time) you place the label.
When you compile this and have the DLL added to the toolbox you can use it. Let's say you add it to a new screen and call it textbox1.
In the propertiesscreen you can change textbox1.TBLabel.Text to HI

When you run the program you will see a blanc tBLabel. Using the de**** will show that textbox1.TBLabel.Text="" But when you add a button with the code textBox1.TBLabel.Text="I'm here" it will show.

So yes I can use the label, but it would be easier if I could pass data to it during designtime using the propertiesbox.

Here's the code that is that should give you an idea:

using System;
using System.Drawing;
using System.ComponentModel;
using System.Windows.Forms;

namespace CLL.WinControls
{
[DesignerCategory("Code")]
public class Textbox : TextBox
{
public Textbox(): base()
{
this.InitializeTB();
base.Enter += new EventHandler(this.NwEnter);
base.KeyDown += new KeyEventHandler(this.NwKeyDown);
base.KeyPress += new KeyPressEventHandler(this.NwKeyPress);
base.KeyUp += new KeyEventHandler(this.NwKeyUp);
base.TextChanged += new EventHandler(this.NwTextChanged);
base.Validating += new CancelEventHandler(this.NwValidating);
base.BindingContextChanged+=new EventHandler(this.NwBindingContextChanged);
base.Disposed += new EventHandler(this.NwDisposed);
tBLabel.DoubleClick += new EventHandler(this.NwTBLabelDoubleClick);
}

private void InitializeTB()
{
tBLabel = new Label();
}





#region New Properties

private ToolTip ErrorMessage = new ToolTip();

private Label tBLabel;//instantiatinge here by stating private Label tBLabel=new Label(); doesn't change the problem
[Description("In properties-box gebruik LABEL....., tBLabel alleen gebruiken bij programmeren.")]
public Label TBLabel
{
get { return tBLabel; }
set { tBLabel = value; }
}

#endregion



#region Events

public new event EventHandler BindingContextChanged;

private void NwBindingContextChanged(object sender, EventArgs e)
{
if (BindingContextChanged != null)
{
BindingContextChanged(sender, e);//First go through the original BindingContextChanged
}
if (!Parent.Controls.Contains(tBLabel))//At startup it passes this routine twice
{
if (labelIsZichtbaar == BoolWaarden.True)
{
tBLabel.Text = label; //Current cheat
tBLabel.Left = Left;
tBLabel.Top = Top - 14;
tBLabel.BackColor = Color.Transparent;
tBLabel.Font = labelFont; //Current Cheat
tBLabel.ForeColor = labelColor; //Current Cheat
Parent.Controls.Add(tBLabel);
}
}
SelectionStart = Text.Length;//Place cursor in textbox at the end
}

Below are the other EVENTS

To make it more readable I left out some properties and events that I use.
There are some properties like label, labelFont, labelColor that I currently use to cheat my problem.
Like this I can atleast assign a labeltext, font and color, but it is not the most elegant way.


I hope this helps.

Kind regards,

Clemens



 
 
TaylorMichaelL





PostPosted: Common Language Runtime, I cannot acces the choosen properties from new component Top

The code I gave will work as you want. The only problem was that the member variable name I used (m_tbLabel) didn't match the private field I declared (tbLabel). A simple compiler warning that you should be able to fix. Nevertheless it'll do what you want.

The problem will be that now you have a label but it'll never show up since the text box will be displayed as a text box and not a label. If you want to display a label next to the text box then you'll need to create a custom control that renders both controls. I guess I still don't understand what you're trying to accomplish. If you want to display static text (or even programmatically change the text either at design time or runtime) then use a label. If you want the user to be able to change the text then use a text box. If you want a label next to a text box then use a composite control. For anything else you'll have to write your own custom control. You should only derive from an existing class if you are going to extend its functionality (such as adding numeric validation to a textbox). In all other cases you should use composition or custom rendering.

Michael Taylor - 10/28/06