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);
}