Problem with the simplest databinding

  • Thread starter Thread starter Balint Toth
  • Start date Start date
B

Balint Toth

Hi all!

I am new to .NET. I would like to bind a string to a textbox. I wrote the
following code:

string text = "hello";

this.textBox1.DataBindings.Clear();

this.textBox1.DataBindings.Add(new Binding("Text",text,""));



The text of the textbox is hello now, but if I change it, than the string
text doesn't change.

What can be the problem?



Thanks in advance!

Best regards,

Balint Toth
 
Well, I also could not get a string to bind to the TextBox correctly.
However I was able to create a class that does bind correctly.

public class BindingTest
{
private string test = "hello"; //this is important

public string Test
{
get{return test;}
set{test = value;}
}
}

and to bind to the TextBox:

//create an instance of BindingTest before binding
BindingTest bindingTest = new BindingTest();
this.textBox1.DataBindings.Add(new Binding("Text", bindingTest, "Test")
 
Thank you for you reply. I tried it, and it worked in case of one-thread
operations. Unfortunately, when I have about 24 threads running, it doesn't
work. I don't know why... Now I just override an event handler to update the
value all the time. Not nice, but working solution.
 
Balint,
Strings in .net are immutable, any code that seems to change a
string is actually creating a new one and the variable is then changed
to point to the new string. So when you you update the textbox it
can't change the string but creates a new one and updates it's
pointer, your variable still points to the original string. The class
approach works because the property is a method call not a memory
location, when the binding infrastructure updates the property it
calls the set method and it binds to the result of the get not to the
actual memory location of the string. When you say it does not work
from multiple threads I assume you mean when you update from other
threads the result is not reflected in the bound textbox. I do not
think this has anything to do with the threading. If you write code
in your form that programatically sets the text property of your
object you will see that the textbox still does not change. The
bindings need to be told that the property has changed, you can do
this by creating an event that is uses the naming convention
PropertynameChanged, you then need to raise this event in the set
method. The class below should do the trick.

public class BindingTest
{
private string text = "hello"; //this is important
==>public event EventHandler TextChanged
public string Text
{
get{return text;}
set{text = value;
==> onTextChanged();
}
}
private void onTextChanged(){
if(TextChanged!=null)
TextChanged(this,EventArgs.Empty);
}
}

There may be one more complication if you are changing the property
from multiple threads. As previously stated forms are not thread
safe, I do not know if databinding is thread safe. If it is not
thread safe you may need to insure the delegate runs on the main
thread, to do this you would need to change the onTextChanged method
as follows(this code is untested):

private void onTextChanged(){
if(TextChanged!=null){
//loop through each registered eventhandler
foreach (EventHandler e in TextChanged.GetInvocationList()){
if (e.Target is Control){ //forms are of type Control
Control ctl = (Control)e.Target;
if (ctl.InvokeRequired()){ //Tells us if we are currently
on the main thread
Object[] args ={this,EventArgs.Empty);
ctl.BeginInvoke(e,args);// executes e on the main
thread using args
}else //Already on main thread
e(this,EventArgs.Empty);
}else // the target is not a control just execute delegate
e(this,EventArgs.Empty);
}
 
Back
Top