simple binding of controls to object properties - refresh controls

G

Guest

I have a dialog with controls bound to class properties, e.g. :
numericUpDownPort.DataBindings.Add("Value", localOptions, "Port");
textBoxDatabaseName.DataBindings.Add("Text", localOptions, "DatabaseName");
textBoxDataUsername.DataBindings.Add("Text", localOptions, "DataUsername");

- i.e. localOptions (a member of the form) is a instance of a class with
properties DatabaseName, Port etc.

My problem is that when the underlying object is refreshed (user can load
the class from a file), the controls don't update. The object's properties
are now different from the user interface.

How to I force the controls to reload their data from the object?

I thought Push/PullData() might be my new friends but these are protected
methods.

Thanks for the help,
Rua HM.

This is a kindoff-followup to "control data binding not happening when data
entered from app"
http://msdn.microsoft.com/newsgroup...t=en-us-msdn&lang=en&cr=US&sloc=en-us&m=1&p=1
 
G

Guest

Here's my workaround, still would like to know whether there is a
correct/better way. I am now reseting the databindings when it's needed (when
the bound object changes). maybe this is the correct way...

// clear data bindings
textBoxServerHostname.DataBindings.Clear();
textBoxDataServerhostname.DataBindings.Clear();

// set data bindings for controls
textBoxServerHostname.DataBindings.Add("Text", localOptions,
"ServerHostname");
textBoxDataServerhostname.DataBindings.Add("Text", localOptions,
"DataServerHostname");
 
S

Sijin Joseph

There is a better way, in you class implement events that fire when the
value of the property changes

for e.g. for the property ServerHostName there should be a corresponding
ServerHostNameChanged event

public class LocalOptions
{

private string _serverHostName;

public event EventHandler ServerHostNameChanged;

public string ServerHostName
{
get{ return _serverHostName; }
set
{
_serverHostName = value;
if(ServerHostNameChanged != null)
ServerHostNameChanged(this,new EventArgs());
}
}

Read this article for good insights into databinding
http://msdn.microsoft.com/library/en-us/dnadvnet/html/vbnet02252003.asp

Sijin Joseph
http://www.indiangeek.net
http://weblogs.asp.net/sjoseph
 
C

Cole

Get the underlying PropertyManager and call ResumeBinding. It calls the
protected OnCurrentChanged() method which calls the protected PushData()
method.

private void RefreshObjectBinding(object obj)
{
PropertyManager pm = (PropertyManager)BindingContext[obj];
pm.ResumeBinding();
}

Cole

I'm not sure how DataBinding chooses between the CurrencyManager and
Rua Haszard Morris said:
I have a dialog with controls bound to class properties, e.g. :
numericUpDownPort.DataBindings.Add("Value", localOptions, "Port");
textBoxDatabaseName.DataBindings.Add("Text", localOptions, "DatabaseName");
textBoxDataUsername.DataBindings.Add("Text", localOptions, "DataUsername");

- i.e. localOptions (a member of the form) is a instance of a class with
properties DatabaseName, Port etc.

My problem is that when the underlying object is refreshed (user can load
the class from a file), the controls don't update. The object's properties
are now different from the user interface.

How to I force the controls to reload their data from the object?

I thought Push/PullData() might be my new friends but these are protected
methods.

Thanks for the help,
Rua HM.

This is a kindoff-followup to "control data binding not happening when data
entered from app":
http://msdn.microsoft.com/newsgroup...951c9-07b2-4c65-b891-baea7036ece5&cat=en-us-m
sdn&lang=en&cr=US&sloc=en-us&m=1&p=1
 
G

Guest

Thanks everyone for all the help - ResumeBinding doesn't appear to do it
after all, but clearing and reset ing all the bindings does, which is a
not-so-bad workaround in my opinion.

I figure that I'm probably using this (data binding) in a way it's not
really supposed to be used... my "data source" is basically a struct with
properties wrapping its members (which explains why I didn't want to fatten
the class up with events!).

Cheers,
Rua HM.

Cole said:
Get the underlying PropertyManager and call ResumeBinding. It calls the
protected OnCurrentChanged() method which calls the protected PushData()
method.

private void RefreshObjectBinding(object obj)
{
PropertyManager pm = (PropertyManager)BindingContext[obj];
pm.ResumeBinding();
}

Cole

I'm not sure how DataBinding chooses between the CurrencyManager and
Rua Haszard Morris said:
I have a dialog with controls bound to class properties, e.g. :
numericUpDownPort.DataBindings.Add("Value", localOptions, "Port");
textBoxDatabaseName.DataBindings.Add("Text", localOptions, "DatabaseName");
textBoxDataUsername.DataBindings.Add("Text", localOptions, "DataUsername");

- i.e. localOptions (a member of the form) is a instance of a class with
properties DatabaseName, Port etc.

My problem is that when the underlying object is refreshed (user can load
the class from a file), the controls don't update. The object's properties
are now different from the user interface.

How to I force the controls to reload their data from the object?

I thought Push/PullData() might be my new friends but these are protected
methods.

Thanks for the help,
Rua HM.

This is a kindoff-followup to "control data binding not happening when data
entered from app":
http://msdn.microsoft.com/newsgroup...951c9-07b2-4c65-b891-baea7036ece5&cat=en-us-m
sdn〈=en&cr=US&sloc=en-us&m=1&p=1
 
C

Chris Jobson

As an experiment I managed to get this to work by implementing the
IBindingList interface in my class and raising the ListChanged event in the
property set code. However, this feels like the wrong solution because to
implement IBindingList you also have to implement IList, ICollection and
IEnumerable - and most of the methods in these interfaces are irrelevant as
the class is NOT actually implementing a list. If you want to see the code
email me and I'll send it to you off-list (but note that I'll be off-line
from the end of this week for about three weeks).

Chris Jobson
 
C

Chris Jobson

I think I've now found the right way to do it. The web page
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dnadvnet/html/vbnet02252003.asp
describes how to do it in VB, and I've just translated it to C# and it
works. Basically if you have a property called Abc then you have to define
an event named AbcChanged, and raise this event when your property changes
(though this seems to be a very well-kept secret!!). Here's the trivial
example that I tested it on:

public class MyString {
string s;

public event EventHandler theStringChanged;

public MyString(string s) {
this.s = s;
}

public string theString {
get { return s; }
set {
if (s != value) {
s = value;
if (theStringChanged != null)
theStringChanged(this, new EventArgs());
}
}
}
}
....
MyString myStr = new MyString("Hello world");
....
textBox1.DataBindings.Add(new Binding("Text", myStr, "theString"));

The textbox is now properly bound to the MyString object: assigning a new
value to myStr.theString updates the textbox, and typing a new value in the
textbox updates myStr.theString when the textBox loses focus.

Chris Jobson
 
G

Guest

Thanks again Chris for looking into this.! Thanks Sijin for already
suggesting this (the correct?) approach.

This is now officially doing my head in - this doesn't work for me. I've
udpated my struct (class!) so that it has event handlers, suitably named (is
it documented anywhere that there is magic binding if eventhandlers are named
appropriately?), and the controls DON'T update!

Can anybody think of a reason why it isn't working for me? I have named
events correctly, but they are not getting set to anything...

Still I think I prefer just manually reseting the bindings, it seems like
bloat to add the eventhandlers & if (event) event() to each set(), anyway!
If the form class needs to handle all those events, forget it, I'll just
reset the bindings!

AND apparently it's all changing for the better in 2005...

My new (wishlist) question is can we define a parent class, which can be
inherited from to provide automatic binding-notification of property changes.
i.e.

class PropertyBindableBase
{
// the magic happens here
}

class SomeProperties : PropertyBindableBase
{
// a nice small simple class with properties, sets and gets
public string Ting
{
get { return stringy; };
set { stringy = value; };
}
private string stringy = "";
}

class BoundForm : Form
{
textbox BobTheBound = new TextBox();
SomeProperties pro = new SomeProperties();
....
Form()
{
BobTheBound.Bindings.Add("Text", someProperties, "Ting")
}
}

???
Anyway there's a nice long posting summing up my thoughts...

cheers all who helped,
Rua HM.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top