Databinding to a business object

T

Tim Jarvis

Hi,

I have an object that I am binding to a text box, this object exposes a
boolean field, and I have implemented a format event handler and a
parse event handler for the binding object, where I convert the bool
value to some meaningful text.

i.e.

Binding b = new
Binding("Text",AppOptions.Instance,"RemoteDataRetrieved");

b.Format += new ConvertEventHandler(RemoteDataRetrievedToString);
b.Parse += new ConvertEventHandler(StringToRemoteDataRetrieved);
textBox1.DataBindings.Add(b);

private void RemoteDataRetrievedToString(object sender,
ConvertEventArgs e)
{
if (e.DesiredType != typeof(string) ) return;
if (e.Value.GetType() != typeof(bool) ) return;
e.Value = (bool) e.Value ? "Remote Data Loaded" : "Remote Data is
not Loaded";
}

private void StringToRemoteDataRetrieved(object sender,
ConvertEventArgs e)
{
if (e.DesiredType != typeof(bool) ) return;
if (e.Value.GetType() != typeof(string) ) return;
e.Value = (string) e.Value == "Remote Data Loaded";
}

(sorry if the formatting is bizarre, my newsreader is wrapping Weirdly)

This actually seems to work ok, except when I change my business
object's property in code, the textbox does not update. I must be
missing something obvious.

Regards Tim.
 
Y

Yan-Hong Huang[MSFT]

Hello Tim,

Thanks for posting in the group.

Based on my understanding, now the problem is: You use simple binding to
bind a object to a text box. However, if you change the value
programmatically, the corresponding textbox won't show the new data. Is it
right?

I started from our WinForm quick start sample at this directory if you
installed .NET framework samples:
C:\Program Files\Microsoft Visual Studio
.NET\FrameworkSDK\Samples\QuickStart\winforms\samples\data\simplebinding\cs

In this project, I added a button to the form and in the OnClick handler of
that button, I added codes:
custList[this.BindingContext[custList].Position+1].FirstName = "Yanhong";

Under this situation, the data of textbox won't be refreshed. Only after
you click next, and then go back, the new value can be shown. In order to
let TextBox to show the newest data, we could add the following code:
textBoxFirstName.Text =
custList[this.BindingContext[custList].Position+1].FirstName;

Besides, in the code, we can set the text field of textbox to the new value
first and then update it to the upderlying binding source.
[C#]
this.textBox1.Text = "XXXX"; //set the value
this.textBox1.DataBindings["Text"].BindingManagerBase.EndCurrentEdit();
//end the edit

Hope that helps.

Best regards,
Yanhong Huang
Microsoft Community Support

Get Secure! ¨C www.microsoft.com/security
This posting is provided "AS IS" with no warranties, and confers no rights.
 
D

Dmitriy Lapshin [C# / .NET MVP]

Gents,

I think the description of the Format and Parse events of the Binding object
might be a very good pointer on when exactly the data is being pooled from
or pushed to the bound data source.

As far as I remember, each of these events has an associated list of
conditions under which it is fired, so this should convey a general idea on
how the data binding mechanics work internally.
 
T

Tim Jarvis

Yan-Hong Huang[MSFT] wrote:

Hope that helps.

Best regards,
Yanhong Huang
Microsoft Community Support

Hi Yan,

Thanks for the reply, unfortunately this does not help me. It seems
that when I bind to a list object (supporting IList or ICollection) I
can get the behaviour that I want, but when I use simple binding to
bind to a non list object , the binding appears to just be one way,
changes to the text in the control updates the business object, but not
the other way around, in fact the PropertyManager that the binding
context gives does not have a refresh property (unlike the
CurrencyManager)

When I started doing some research into this, I came across a reference
to the longhorn interface IPropertyChanged which appears to address
what I want (for longhorn at least), but I must admit I thought that
the data binding mechanism ( and context managers) took care of this.

A work around appears to be to remove the binding
(Databindings.Clear()) and rebind the object, is this the recommended
way to do this, or is there a better way ?

Regards Tim.
 
T

Tim Jarvis

Dmitriy said:
Gents,

I think the description of the Format and Parse events of the Binding
object might be a very good pointer on when exactly the data is being
pooled from or pushed to the bound data source.

As far as I remember, each of these events has an associated list of
conditions under which it is fired, so this should convey a general
idea on how the data binding mechanics work internally.

Thanks for the reply Dmitriy, I guess the format and parse events are
what got me started down this binding route, and I reckon that simple
databinding to business objects is 98% of the way there, there are just
a couple of annoyances, where you are led to believe that it works a
particular way, and it sorta does, just misses slightly.

What I want to be able to do is create an edit dialog that binds to a
business object that I pass in, note the business object is not a list,
just a simple object (in this test case an application options object),
and this works great, when I use the GUI widgets to update the business
object properties, the issue is that I would also like to update the
business object in code elsewhere and have the bound form reflect the
changes, this is where the binding falls a bit short, the work around
appears to be to remove the bindings and reapply them (not a big deal
actually, as I have a binding function anyway) just seems a bit of a
cludge, I expected to see a refresh method in the property manager.

Hope that makes sense.

Regards Tim.
 
Y

Yan-Hong Huang[MSFT]

Hi Tim,

So your object is not based on list, right?

I created a simple object for testing here

public class testobj
{
private string intlval;
public string testmember
{
get
{
return intlval;
}
set
{
intlval=value;
}
}
}

The rebind method that you are using now should work. Besides, in the
Onclick hanlder of the button, we can also use SuspendBinding and
ResumeBinging of bindingmanagerbase to acheieve it. Please refer to the
following code sample:

testobj o=(testobj)b.BindingManagerBase.Current;
o.testmember="xixi";
b.BindingManagerBase.SuspendBinding();
b.BindingManagerBase.ResumeBinding();

I tested it and it works fine.

Here is one explanation from MVP Nicholas Paldino:
---------------
Using the BindingContext and populating the list are two different
things. While they both have to deal with data and the properties of the
ComboBox, they definitely are different.

The BindingContext, and calling SuspendBinding and ResumeBinding, will have
the effect of not updating the ComboBox properties itself when making
changes to a data source that it is bound to. For example, if you have a
table with two fields in it, "Text" and "MaxLength", you can have a
ComboBox bound to those two fields, binding the Text and MaxLength
properties respectively. Now, if you call SuspendBinding on this table,
then when you change the Text and MaxLength values in the table, the
ComboBox properties
which are bound to these columns will not change until you call
ResumeBinding.

Now, this is completely different to the list of items, which you have to
set in the data source. If your data source doesn't implement
IBindingList, then the combobox items will not be updated when you add a
new item to the underlying data source. If you change the underlying data
source, then you will have to set the data source again on the combobox,
forcing a complete re-binding to the list data source. This can be very
prohibitive though, so you might want to look into using a data source that
implements IBindingList.
-----------------------

Hope that helps.

Best regards,
Yanhong Huang
Microsoft Community Support

Get Secure! ¨C www.microsoft.com/security
This posting is provided "AS IS" with no warranties, and confers no rights.
 
D

Dmitriy Lapshin [C# / .NET MVP]

Tim,
and this works great, when I use the GUI widgets to update the business
object properties, the issue is that I would also like to update the
business object in code elsewhere and have the bound form reflect the
changes, this is where the binding falls a bit short, the work around
appears to be to remove the bindings and reapply them (not a big deal

I remember I have read somewhere your business object should expose events
fired when its properties change. Say, if you have a Contact business
object, and it has a Name property, you should expose a NameChanged event
and fire it whenever the value of the Name property changes. I believe it
were MSDN articles on data binding (and NOT the class library reference)
where I've found this information.
 
T

Thomas Tomiczek [MVP]

Alternatively - this is the way I do it in our EntityBroker, as I have no
intention to clutter a busienss object interface with 20+ events - you can
expose ONE change event and make sure your own PropertyDescriptors get used,
which are then able to subscribe to this central changed event and "divide
it apart" again. Works like a charm.

--
Regards

Thomas Tomiczek
THONA Software & Consulting Ltd.
(Microsoft MVP C#/.NET)
(CTO PowerNodes Ltd.)
---

Still waiting for ObjectSpaces? Try the EntityBroker today - more versatile,
more powerfull.
And something in use NOW. for the projects you have to deliver - NOW.


Dmitriy Lapshin said:
Tim,
and this works great, when I use the GUI widgets to update the business
object properties, the issue is that I would also like to update the
business object in code elsewhere and have the bound form reflect the
changes, this is where the binding falls a bit short, the work around
appears to be to remove the bindings and reapply them (not a big deal

I remember I have read somewhere your business object should expose events
fired when its properties change. Say, if you have a Contact business
object, and it has a Name property, you should expose a NameChanged event
and fire it whenever the value of the Name property changes. I believe it
were MSDN articles on data binding (and NOT the class library reference)
where I've found this information.

--
Dmitriy Lapshin [C# / .NET MVP]
X-Unity Test Studio
http://www.x-unity.net/teststudio.aspx
Bring the power of unit testing to VS .NET IDE

Tim Jarvis said:
Thanks for the reply Dmitriy, I guess the format and parse events are
what got me started down this binding route, and I reckon that simple
databinding to business objects is 98% of the way there, there are just
a couple of annoyances, where you are led to believe that it works a
particular way, and it sorta does, just misses slightly.

What I want to be able to do is create an edit dialog that binds to a
business object that I pass in, note the business object is not a list,
just a simple object (in this test case an application options object),
and this works great, when I use the GUI widgets to update the business
object properties, the issue is that I would also like to update the
business object in code elsewhere and have the bound form reflect the
changes, this is where the binding falls a bit short, the work around
appears to be to remove the bindings and reapply them (not a big deal
actually, as I have a binding function anyway) just seems a bit of a
cludge, I expected to see a refresh method in the property manager.

Hope that makes sense.

Regards Tim.
 
T

Tim Jarvis

Yan-Hong Huang[MSFT] wrote:

testobj o=(testobj)b.BindingManagerBase.Current;
o.testmember="xixi";
b.BindingManagerBase.SuspendBinding();
b.BindingManagerBase.ResumeBinding();

I tested it and it works fine.

Thanks Yan,

This looks like it is what I want, I have a question though, how do I
get the correct BindingManagerBase object (what is your b object in
your example ?), for example if I bind my class to (say) a text box
i.e. textBox1.DataBindings.Add(new
Binding("Text",TestObject,"MyField"));

again, thanks for your help with this so far.

Cheers Tim.
 
D

Dmitriy Lapshin [C# / .NET MVP]

Thomas,

Could you post a simple example? I remember it was mentioned in MSDN that a
single notification event named PropertyChanged or something similar could
be used, but I wasn't able to find neither more details nor a complete
example.

--
Dmitriy Lapshin [C# / .NET MVP]
X-Unity Test Studio
http://www.x-unity.net/teststudio.aspx
Bring the power of unit testing to VS .NET IDE

Thomas Tomiczek said:
Alternatively - this is the way I do it in our EntityBroker, as I have no
intention to clutter a busienss object interface with 20+ events - you can
expose ONE change event and make sure your own PropertyDescriptors get used,
which are then able to subscribe to this central changed event and "divide
it apart" again. Works like a charm.

--
Regards

Thomas Tomiczek
THONA Software & Consulting Ltd.
(Microsoft MVP C#/.NET)
(CTO PowerNodes Ltd.)
---

Still waiting for ObjectSpaces? Try the EntityBroker today - more versatile,
more powerfull.
And something in use NOW. for the projects you have to deliver - NOW.


Dmitriy Lapshin said:
Tim,
and this works great, when I use the GUI widgets to update the business
object properties, the issue is that I would also like to update the
business object in code elsewhere and have the bound form reflect the
changes, this is where the binding falls a bit short, the work around
appears to be to remove the bindings and reapply them (not a big deal

I remember I have read somewhere your business object should expose events
fired when its properties change. Say, if you have a Contact business
object, and it has a Name property, you should expose a NameChanged event
and fire it whenever the value of the Name property changes. I believe it
were MSDN articles on data binding (and NOT the class library reference)
where I've found this information.

--
Dmitriy Lapshin [C# / .NET MVP]
X-Unity Test Studio
http://www.x-unity.net/teststudio.aspx
Bring the power of unit testing to VS .NET IDE

Tim Jarvis said:
Dmitriy Lapshin [C# / .NET MVP] wrote:

Gents,

I think the description of the Format and Parse events of the Binding
object might be a very good pointer on when exactly the data is being
pooled from or pushed to the bound data source.

As far as I remember, each of these events has an associated list of
conditions under which it is fired, so this should convey a general
idea on how the data binding mechanics work internally.

Thanks for the reply Dmitriy, I guess the format and parse events are
what got me started down this binding route, and I reckon that simple
databinding to business objects is 98% of the way there, there are just
a couple of annoyances, where you are led to believe that it works a
particular way, and it sorta does, just misses slightly.

What I want to be able to do is create an edit dialog that binds to a
business object that I pass in, note the business object is not a list,
just a simple object (in this test case an application options object),
and this works great, when I use the GUI widgets to update the business
object properties, the issue is that I would also like to update the
business object in code elsewhere and have the bound form reflect the
changes, this is where the binding falls a bit short, the work around
appears to be to remove the bindings and reapply them (not a big deal
actually, as I have a binding function anyway) just seems a bit of a
cludge, I expected to see a refresh method in the property manager.

Hope that makes sense.

Regards Tim.
 
D

Dmitriy Lapshin [C# / .NET MVP]

You can obtain the BindingManagerBase from the form's BindingContext
property. Specify TestObject as the data source and "MyField" as the data
member.

--
Dmitriy Lapshin [C# / .NET MVP]
X-Unity Test Studio
http://www.x-unity.net/teststudio.aspx
Bring the power of unit testing to VS .NET IDE

Tim Jarvis said:
Yan-Hong Huang[MSFT] wrote:

testobj o=(testobj)b.BindingManagerBase.Current;
o.testmember="xixi";
b.BindingManagerBase.SuspendBinding();
b.BindingManagerBase.ResumeBinding();

I tested it and it works fine.

Thanks Yan,

This looks like it is what I want, I have a question though, how do I
get the correct BindingManagerBase object (what is your b object in
your example ?), for example if I bind my class to (say) a text box
i.e. textBox1.DataBindings.Add(new
Binding("Text",TestObject,"MyField"));

again, thanks for your help with this so far.

Cheers Tim.
 
T

Tim Jarvis

Thomas said:
Alternatively - this is the way I do it in our EntityBroker, as I
have no intention to clutter a busienss object interface with 20+
events - you can expose ONE change event and make sure your own
PropertyDescriptors get used, which are then able to subscribe to
this central changed event and "divide it apart" again. Works like a
charm.

Hi Thomas and Dmitriy,

Yeah, there are a few common patterns for this, especially common in
OPF's (object persistant frameworks)

I was kinda hoping for the binding mechanism to have implemented this
pattern for me with simple binding, as it has with complex binding. And
let's face it, it is 98% of the way there, when you add the initial
binding, it makes the update to the GUI, seems to me that a simple
refresh, would solve the problem. Yan's suspend and resume looks like
the ticket, if I can work out how to get the correct binding manager
from the bindingcontext collection.

Cheers Tim.
 
T

Tim Jarvis

Dmitriy said:
You can obtain the BindingManagerBase from the form's BindingContext
property. Specify TestObject as the data source and "MyField" as the
data member.

Ahh, thanks for that. (I was missing the "MyField" bit)

I guess though that this means I am going to have a PropertyManager
(BindingManagerBase) for each property of my Object, Which make perfect
sense when you think about it, I had wrongly assumed that I would get
just one PropertyManager for the entire Business Object.

So I have a way forward with what I want to do, effectivly though for
Object->widget binding I will have to implement an observer type
pattern on my Business Object and either suspend and resume or clear
and re-bind my bound widgets for whatever property that has changed.

I was hoping that the .net framework would do this for me, but you
can't have everything :) I guess the longhorn IPropertyChanged
interface will address this to some extent, I don't know enough about
longhorn to know what else is built in for this type of 2 way binding
behaviour.

Don't get me wrong, having the auto updating of the business object
from the gui widgets is pretty huge and I really like it, and with just
a little extra work this can be a very nice solution to this common
pattern of app development.

Thanks to All for your help.

Regards Tim.
 
T

Thomas Tomiczek [MVP]

Let me tell ou that we there where you are some time ago, and we just
decided it is NOT worth the effort.

Databinding in .NET 1.0/1.1 is very focused on binding against alist of
objects. Dataset like.

So we play nice now.

* We have an ObjectView you drop onto the form that serves as data source.
Typed.
* Objects go intoa ObjectBindingList (autogenerated in the ObjectView if
necessary).

So, all binding in a form is against the view, and you dump your object (or
list of objects) into the view.

This makes a LOT of things a LOT easier. And really a lot. Suddenly
databinding starts to work without TOO many snafus.

Although there still are a LOT - like a nice inability to handle "NULL" in
textfields (from the MS controls).

--
Regards

Thomas Tomiczek
THONA Software & Consulting Ltd.
(Microsoft MVP C#/.NET)
(CTO PowerNodes Ltd.)
 
T

Tim Jarvis

Thomas said:
Let me tell ou that we there where you are some time ago, and we just
decided it is NOT worth the effort.

Databinding in .NET 1.0/1.1 is very focused on binding against alist
of objects. Dataset like.

So we play nice now.

* We have an ObjectView you drop onto the form that serves as data
source. Typed.
* Objects go intoa ObjectBindingList (autogenerated in the ObjectView
if necessary).

So, all binding in a form is against the view, and you dump your
object (or list of objects) into the view.

This makes a LOT of things a LOT easier. And really a lot. Suddenly
databinding starts to work without TOO many snafus.

Although there still are a LOT - like a nice inability to handle
"NULL" in textfields (from the MS controls).

Thanks Thomas (can I call you Tom ?)

This sounds like an interesting approach, I will have a look along
these lines as well.

Food for thought, thanks.

Cheers Tim.
 
T

Thomas Tomiczek [MVP]

It has another advantage.

You drop the ObjectView on the form at design time, then select the Class
type included (at design time, using a nice selection dialog).

And then you suddenly have all the lost visual designer support again that
Datasets have :)

--
Regards

Thomas Tomiczek
THONA Software & Consulting Ltd.
(Microsoft MVP C#/.NET)
(CTO PowerNodes Ltd.)
 

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