Spulit

Hi,

I'm having troubles with a data binding between a label text and a class property. I have a class like this:

public ref class TestClass : public INotifyPropertyChanged
{
public:
virtual event PropertyChangedEventHandler ^PropertyChanged
{
void add(PropertyChangedEventHandler^ value) { this->propertyChanged += value; }
void remove(PropertyChangedEventHandler^ value) { this->propertyChanged -= value; }
};
virtual void NotifyPropertyChanged(String ^info) override
{
propertyChanged(this, gcnew PropertyChangedEventArgs(info));
};
property unsigned int ToW
{
void set(unsigned int tow_){
tow = tow_;
NotifyPropertyChanged("ToW");
}
unsigned int get()
{
return tow;
}
};
private:
unsigned int tow;
event PropertyChangedEventHandler ^propertyChanged;
};

And I have a window where I have label which I want it to be automatically updated as the property "ToW" in the class above is changed. So I define the following databinding:

this->labelToW->DataBindings->Add(gcnew Binding("Text", testClass, "ToW"));

"testClass" is an instance of TestClass.
However, when I update the "ToW" property, the label doesn't get updated and I get an error like this:

"Cross-thread operation not valid: Control 'labelToW' accessed from a thread other than the thread it was created on."

I guess the problem is that ToW property is updated by another thread I run to listen to a socket.
Is there any workaround to this problem
Am I missing something

Thanks,

Spulit



Re: Windows Forms Data Controls and Databinding Automatic update of label text bound to a class property updated by another thread

Luc Morin

Hi,

Calling methods on GUI elements must be done within the GUI thread.

Look up the Control.Invoke() in MSDN. It is used to marshall a call from another thread back to the GUI thread.

Hope this helps.

Luc





Re: Windows Forms Data Controls and Databinding Automatic update of label text bound to a class property updated by another thread

Spulit

Hi Luc,

Thanks for your reply. The problem is that it is the internal binding service that calls the GUI label, not my code.I do not control the way the binding updates the label's text value when my other thread updates the value in the class property that is on the other side of the binding.
How can I assure the binding calls the invoke() method

Thanks,

Spulit





Re: Windows Forms Data Controls and Databinding Automatic update of label text bound to a class property updated by another thread

Luc Morin

Hi,

Even if it's the Binding object that modifies the GUI, it still gets executed on your other thread, so the GUI modifying call ends up in a non-GUI thread.

What you could do is wrap the call to your class' "setter" in the call to Invoke(), this way everything is handled by the GUI thread. It's the call to NotifyPropertyChange() that triggers the binding mechanism, so you'd want to make sure that at least this call is on the UI thread.

By the way, I'm not saying this is the only solution. It's the first one that comes to my mind.

Luc





Re: Windows Forms Data Controls and Databinding Automatic update of label text bound to a class property updated by another thread

Spulit

Hi Luc,

I trying to have a complete separation between the logic part and the GUI part. I mean, the class "TestClass" defined above doesn't know anything about the GUI.
How would you change the code above to fit your suggestion

Thanks again,

Spulit







Re: Windows Forms Data Controls and Databinding Automatic update of label text bound to a class property updated by another thread

Spulit

Hi,

I managed to solve the problem by setting my other thread as a BackgroundWorker and then updating the class property in the RunWorkerCompletedEventHandler. This handler in turn keeps calling RunWorkerAsync() in order to start the thread over again. I would like the BackgroundWorker to never stop but then the RunWorkerCompletedEventHandler is never called...Don't know if it is an elegant solution, but it works...

Thanks,

Spulit






Re: Windows Forms Data Controls and Databinding Automatic update of label text bound to a class property updated by another thread

Luc Morin

Hi,

Though your data class doesn't know anything about UI, surely it needs to be accessible to the UI somehow in order for databinding to work, right

Also, I assume your secondary thread is started from the UI thread. This indicates that you could marshall the call that updates the data object to the UI thread in different ways.

For example, within your secondary thread, you could use Control.Invoke to do the actual setting of the data properties on the object (or you could also use Control.BeginInvoke if you want this call to be async).

Also, I have found this piece of information on MSDN:

http://msdn2.microsoft.com/en-us/library/ms184414.aspx. Please note the following on this page:

If your data source implements INotifyPropertyChanged and you are performing asynchronous operations, you should not make changes to the data source on a background thread. Instead, you should read the data on a background thread and merge the data into a list on the UI thread.

Hope this helps.





Re: Windows Forms Data Controls and Databinding Automatic update of label text bound to a class property updated by another thread

Luc Morin

Hi,

I found this interesting thread:

http://forums.microsoft.com/MSDN/ShowPost.aspx PostID=65024&SiteID=1

If you look at Joe Stegman's reply to the original poster, he gives a method to marshall such a call to the UI thread.

Hope this helps.