Odd databinding behavior

G

Guest

Hi all,

I’ve got a databinding inquiry. I’ve got a very simple example: a VB.Net
winforms app, with 3 components:

2 textboxes, and a button. Here are the handlers:

Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As
System.EventArgs) Handles Button1.Click
TextBox1.DataBindings("Text").WriteValue()
TextBox2.DataBindings("Text").WriteValue()

My.Settings.Save()
End Sub

Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As
System.EventArgs) Handles MyBase.Load
TextBox1.DataBindings.Add("Text", My.Settings, "val1", False,
DataSourceUpdateMode.Never)
TextBox2.DataBindings.Add("Text", My.Settings, "val2", False,
DataSourceUpdateMode.Never)
End Sub

As you can guess, there’s 2 settings: val1 and val2. If I just do regular
databinding which updates on its own (rather than
DataSourceUpdateMode.Never), no problems. But using the .never mode and doing
the update manually for each value with .writevalue, only one of the two
values gets written. For the other, the previous value remains. I’ve
discovered a possible reason:

Look at this stack trace:
WindowsApplication8.exe!WindowsApplication8.My.MySettings.get_Val2() Line 74 Basic
[External Code]
WindowsApplication8.exe!WindowsApplication8.My.MySettings.set_Val1(String
Value = "apple") Line 65 + 0xe bytes Basic
[External Code]
WindowsApplication8.exe!WindowsApplication8.Form1.Button1_Click(Object
sender = {Text = "Button1"}, System.EventArgs e =
{System.Windows.Forms.MouseEventArgs}) Line 4 + 0x32 bytes Basic
[External Code]

Setting value 1 seems to trigger a refresh of the original value 2, which is
likely why it’s not getting the new value written. Is this because the two
share a binding context? What’s the thinking behind this? Why is it that this
problem doesn’t occur when I don’t set it to “.never�

PS: what is the “external code†in the above trace?

Thanks…

-Ben
 
K

Kevin Yu [MSFT]

Hi Ben,

Thank you for the repro sample. I can reproduce it on my machine. It looks
like a bug. Currently, I'm contacting the product team to see if there is a
workaround, and will let you know ASAP. Thank you!

Kevin Yu
Microsoft Online Community Support

==================================================
Get notification to my posts through email? Please refer to
http://msdn.microsoft.com/subscriptions/managednewsgroups/default.aspx#notif
ications.
Note: The MSDN Managed Newsgroup support offering is for non-urgent issues
where an initial response from the community or a Microsoft Support
Engineer within 1 business day is acceptable. Please note that each follow
up response may take approximately 2 business days as the support
professional working with you may need further investigation to reach the
most efficient resolution. The offering is not appropriate for situations
that require urgent, real-time or phone-based interactions or complex
project analysis and dump analysis issues. Issues of this nature are best
handled working with a dedicated Microsoft Support Engineer by contacting
Microsoft Customer Support Services (CSS) at
http://msdn.microsoft.com/subscriptions/support/default.aspx.
==================================================

(This posting is provided "AS IS", with no warranties, and confers no
rights.)
 
K

Kevin Yu [MSFT]

Hi Ben

I have reported this issue to the product team. Currently, they are
researching on it. If you need a solution or a hotfix in short time, I
suggest you contact Microsoft PSS. If this has been confirmed a bug, there
will be no charge. You can find their contact information from the
following link:

http://support.microsoft.com/common/international.aspx?rdpath=gp;en-us;offer
prophone

Kevin Yu
Microsoft Online Community Support
==================================================

(This posting is provided "AS IS", with no warranties, and confers no
rights.)
 
G

Guest

Hi Kevin,

I don't need an immediate hotfix, but could you give me a defect tracking
number? You can email it directly to me if you prefer. Also, if you could
share some insight about the stack trace (with set triggering a get), that
would be helpful, if such info is available to you. Do you have any sense as
to how long until there's more info on this?

Thanks...

-Ben
 
B

Bart Mermuys

Hi,

Ben R. said:
Hi Kevin,

I don't need an immediate hotfix, but could you give me a defect tracking
number? You can email it directly to me if you prefer. Also,
if you could
share some insight about the stack trace (with set triggering a get), that
would be helpful, if such info is available to you.

When you push the value from Control to DataSource, then the DataSource
(My.Settings) will fire a PropertyChanged event for the setted property.
Both your Bindings are maintained by a PropertyManager (or CurrencyManager)
and when a PropertyChanged event is fired for any property it will force all
Bindings (except the one that was writing) to read the values from
DataSource to Control.

If you use the default DataSourceUpdateMode, then a value is pushed to the
DataSource when the user leaves the Control (Validating), so there can only
be one Control with a dirty value, and then you don't see this problem.

A BindingSource can be used to block the PropertyChanged event going from
DataSource to CurrencyManager, eg:.

Private SettingsBS As BindingSource

Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As
System.EventArgs) Handles MyBase.Load

SettingsBS = new BindingSource(My.Settings, "")

TextBox1.DataBindings.Add("Text", SettingsBS, "val1", False,
DataSourceUpdateMode.Never)
TextBox2.DataBindings.Add("Text", SettingsBS, "val2", False,
DataSourceUpdateMode.Never)

End Sub

Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As
System.EventArgs) Handles Button1.Click

SettingsBS.FireListChangeNotifications = False

TextBox1.DataBindings("Text").WriteValue()
TextBox2.DataBindings("Text").WriteValue()

SettingsBS.FireListChangeNotifications = True

My.Settings.Save()
End Sub

HTH,
Greetings



Do you have any sense as
 
B

Bart Mermuys

Bart Mermuys said:
Hi,




When you push the value from Control to DataSource, then the DataSource
(My.Settings) will fire a PropertyChanged event for the setted property.
Both your Bindings are maintained by a PropertyManager (or
CurrencyManager) and when a PropertyChanged event is fired for any
property it will force all Bindings (except the one that was writing) to
read the values from DataSource to Control.

If you use the default DataSourceUpdateMode, then a value is pushed to the
DataSource when the user leaves the Control (Validating), so there can
only be one Control with a dirty value, and then you don't see this
problem.

A BindingSource can be used to block the PropertyChanged event going from
DataSource to CurrencyManager, eg:.

Private SettingsBS As BindingSource

Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As
System.EventArgs) Handles MyBase.Load

SettingsBS = new BindingSource(My.Settings, "")

TextBox1.DataBindings.Add("Text", SettingsBS, "val1", False,
DataSourceUpdateMode.Never)
TextBox2.DataBindings.Add("Text", SettingsBS, "val2", False,
DataSourceUpdateMode.Never)

End Sub

Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As
System.EventArgs) Handles Button1.Click

SettingsBS.FireListChangeNotifications = False

TextBox1.DataBindings("Text").WriteValue()
TextBox2.DataBindings("Text").WriteValue()

SettingsBS.FireListChangeNotifications = True

Should be RaiseListChangedEvents

Greetings
 
K

Kevin Yu [MSFT]

Thank you Bart for you input. Ben, do you still have problem on this issue?

Kevin Yu
Microsoft Online Community Support
==================================================

(This posting is provided "AS IS", with no warranties, and confers no
rights.)
 
B

Bart Mermuys

Hi,

Ben R. said:
HI Bart,

Thanks very much for your response. It seems that this is therefore not a
bug.

I wouldn't go that far, it's still unexpected behaviour and would still
consider it a bug. The question is: why do the other properties need to be
read when one is set ? I don't see much benefit from this, besides that
caculated properties don't need to fire any PropertyChanged.
I need to familiarize myself with the bindingsource class. As I think
further, I should be able to achieve the same result also by:

calling "suspendbinding" on the bindingcontext before doing the update
or

Don't confuse BindingContext with a PropertyManager or CurrencyManager.
Calling SuspendBinding on a PropertyManager (which you can get from the
BindingContext) seems like an option, but AFAIK it doesn't block all
events...so i don't believe it will work.
by setting up separate bindingcontexts for the properties (though this
doesn't seem like a good solution).

If you would set a different BindingContext to each TextBox, eg:
TextBox1.BindingContext = new BindingContext()
TextBox2.BindingContext = new BindingContext()

And then setup the binding without a BindingSource, then the Binding's would
each have a different PropertyManager which is owned by each BindingContext.
So this might work, but only because you are binding to an object, if you
would bind to a list, then they would each have a different CurrencyManager
and not navigate together.

This is similar as to binding to two different BindingSource's which have
the same DataSource.

In NET1.1 both PropertyManager and CurrencyManager are own by a
BindingContext.

In NET2.0 the BindingSource:
puts single objects into a list
owns the CurrencyManager
wraps the list (allowing it to block notifying events)


HTH,
Greetings
In addition to your thought, I'll experiment with these.

I think
 
K

Kevin Yu [MSFT]

Thank you, Ben. Anyway, I have reported this to the product team and they
may decide whether it is. Thanks again for your feedback.

Kevin Yu
Microsoft Online Community Support
==================================================

(This posting is provided "AS IS", with no warranties, and confers no
rights.)
 

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