Home
Help
Register
Log in

Search

 
   Active Threads  

You are here: Home > LLBLGen Pro > LLBLGen Pro Runtime Framework> Fields 'resurrecting' themselves when databound...
 

Pages: 1
LLBLGen Pro Runtime Framework
Fields 'resurrecting' themselves when databound...
Page:1/1 

  Print all messages in this thread  
Poster Message
JSobell
User



Location:

Joined on:
07-Jan-2006 06:44:46
Posted:
89 posts
# Posted on: 20-Mar-2008 07:04:26.  
I've been struggling with this all afternoon, and it may be nothng to do with LLBLGen, but I'm exhausting my list of otherplaces to look...

I have a form full of databound components. They link to an Entity via an object bindingSource. The bindingSource's datamember is set to an entity, and various form components are bound to various fields.

Everything worked fine until I decided to add some programmatic setting of data. When the user enters an 'EnteredBy' value (bound to EnteredBy field) I lookup their email, and attempt to populate that into the 'Email' field.
But, as soon as I attempt to write a value into the 'Email' field, the entity calls
"SetValue((int)MovementFieldIndex.EnteredBy, value, true)"
which proceeds to call each GetValue in the object, and appears to reset the control that was last edited back to its previous value.
What is the 'correct' process to follow when committing data to the object (i.e. before .Save() is called) on a databound form?

I would love to post an example, and will try to if nobody has any suggestions, but the current form uses a myriad of third-party components, and I thought I'd put some feelers out there before developing a whole stand-alone example.

Cheers,
Jason
  Top
daelmo
Support Team



Location:
Guatemala City
Joined on:
28-Nov-2005 23:35:24
Posted:
8108 posts
# Posted on: 20-Mar-2008 07:15:36.  
How are you setting the Email field? (could you post just that code snippet) because I think that lookup for the email and show up shouldn't call the SetValue on EnteredBy field.

Quote:
What is the 'correct' process to follow when committing data to the object (i.e. before .Save() is called) on a databound form?

That depends upon what you want to accomplish. For example, you could use ValidateEntityBeforeSave, AuditOnEntitySave, PreProcessValue, and a some entity events. What are you trying to accomplish before save method?


David Elizondo
LLBLGen'ing (articles and code snippets) | linkedin | twitter
 
Top
JSobell
User



Location:

Joined on:
07-Jan-2006 06:44:46
Posted:
89 posts
# Posted on: 20-Mar-2008 07:31:58.  
daelmo wrote:
How are you setting the Email field? (could you post just that code snippet) because I think that lookup for the email and show up shouldn't call the SetValue on EnteredBy field.


I tried setting the Text property of thebound control, and writing directly to the Entity.
I've finally got something working by setting both the Email and EnteredBy properties on the Entity. If I set either one independently then the other get's 'stonked on' by the underlying object.
It's obviously something weird about data binding, as this never happens when using Entities directly.

As pseudo-code, here is the effect I experienced:
Code:

Entity current = new MyEntity(123);
(txtEnteredBy and txtEmail are bound to current)
current contains 'Albert' and 'a@a.com'.
existing data shows 'Albert' in txtEntered, and 'a@a.com' in txtEmail.
User enters 'Bob' into txtEnteredby, then clicks '[Save]'
Leave event fires on txtEntered, and runs the following:

string was = txtEnteredby.Text;
current.Email = txtEnteredby.Text + "@dodo.com";
string isnow = txtEnteredby.Text;

'was' contains 'Bob', as expected,
but for some reason 'isnow' has reverted back to 'Albert' again!.


Stepping the code shows the call to SetValue, then a series of calls to GetValue, but the reason is hidden in the compiled LLBLGen code, so I don't know what triggered the fetches.

Cheers,
Jason
  Top
Walaa
Support Team



Location:

Joined on:
21-Aug-2005 16:03:48
Posted:
14584 posts
# Posted on: 20-Mar-2008 09:51:46.  
Quote:
string was = txtEnteredby.Text;
current.Email = txtEnteredby.Text + "@dodo.com";
string isnow = txtEnteredby.Text;


I think the problem is when to use this code, and whether to use TextBox values or entity field values.
I have a feeling that you are interfering with the databinding edit-cycle.
And that's the above code is called before EndEdit() was called.


  Top
JSobell
User



Location:

Joined on:
07-Jan-2006 06:44:46
Posted:
89 posts
# Posted on: 21-Mar-2008 13:09:16.  
Yes, and for those wanting to experiment with it, there's some simple code below that shows it happening with any databound object. Just drop two text boxes, a button, and a BindingSource, then bind Name to the first box, Email to the other.

I always hated data-bound GUIs, and having to code in all these EndCurrentEdit statements is very messy.

In this case you must do both of the statements below marked with "****". It appears to be a common requirement, updating one field based on the value in another, but it turns out to be a little more complex than expected Regular Smiley

Cheers,
Jason

Code:

    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        PretendEntity pe = new PretendEntity() { Name = "Fred", eMail = "Fred@initial.com" };

        private void Form1_Load(object sender, EventArgs e)
        {
            bindingSource1.DataSource = pe;
        }

        private void textBox1_Leave(object sender, EventArgs e)
        {
            textBox1.BindingContext[bindingSource1].EndCurrentEdit(); //*************
            textBox2.Text = textBox1.Text + "@where.com";
        }

        private void button1_Click(object sender, EventArgs e)
        {
            BindingContext[bindingSource1].EndCurrentEdit(); //*************
            MessageBox.Show(string.Format("Name={0}, Email={1}", pe.Name, pe.eMail));
        }
    }

    public class PretendEntity
    {
        public int ID { get; set; }
        public string Name { get; set; }
        public string eMail { get; set; }
    }
  Top
simmotech
User



Location:

Joined on:
01-Feb-2006 15:43:00
Posted:
1006 posts
# Posted on: 21-Mar-2008 14:13:11.  
Hi Jason

Your PretendEntity doesn't have OnChanged events or implement INotifyPropertyChanged - Binding sometimes works differently when these are not present. Though I don't think it matters in this particular case, watch out when debugging other binding issues.

I think the problem is that the default binding created using the designer updates the DataSource on Validation but if you change it to DataSourceUpdateMode.OnPropertyChanged, I think you will achieve what you want.

If you create your bindings by hand in a Load event or whatever, it should look something like this:
Code:
    this.textBox1.DataBindings.Add(new System.Windows.Forms.Binding("Text", this.bindingSource1, "Name", true, System.Windows.Forms.DataSourceUpdateMode.OnPropertyChanged));

If you prefer to use the designer, click on (Advanced) under (DataBindings) and change the DataSourceUpdate mode there.

Make this change for both bindings and it works as expected.

Cheers
Simon

PS I've found that whenever you use OnPropertyChanged, you MUST have the preceeding boolean set to True!


  Top
JSobell
User



Location:

Joined on:
07-Jan-2006 06:44:46
Posted:
89 posts
# Posted on: 22-Mar-2008 14:12:01.  
Thanks Simon, I'll check this out next week.
I must admit that I'm no expert at .NET's data binding, and this is all excellent information. This sort of issue tends to drag out to days of work (often ending with a completely unnecessary bodge workaround), so this information is very much appreciated.

Many thanks,
Jason
  Top
Pages: 1  


Powered by HnD ©2002-2007 Solutions Design
HnD uses LLBLGen Pro

Version: 2.1.12172008 Final.