Hi guys,
Thanks for taking the time to read my post.
I'm having a strange issue with business objects bound to Windows controls and some changes not being reflected. I'm hoping one of you guys has seen this before and can offer some suggestions.
I am using CSLA version 2.1.4.0. I’ve created a Purchase Order object (editable root), which contains a Payments collection (editable child list), which holds Payments objects (editable child).
I set up each of these objects as a "Data Source" in Visual Studio 2005, so I could drag and drop the objects or their properties onto a Windows form as bound controls.
At the top of my Windows form, I dragged the Payments collection onto the form as a DataGridView. I set the DataGridView to readonly because I do not want the users making changes directly inside the grid. The grid displays only minimal payment information necessary to help the user identify which payment he/she is looking for.
At the bottom of the form I dragged various properties from the Payments object, like "Amount" or "Payment Type", onto the form as textboxes, listboxes, etc. These controls show all detailed information about one payment.
My intentions for this layout are that the user will select a payment in the DataGridView at the top of the form and then at the bottom of the form the user will view or edit all the details of the selected payment using the various textboxes, listboxes, etc.
At the bottom of the form, I also placed an "Add" button for adding new payments (to the Payments collection and DataGridView) and a “Remove” button for removing them.
At first it appeared that everything worked as I expected. For example, I would make a change to the "Amount" textbox at the bottom of the screen and once I tabbed away from the textbox, the "Amount" value would also change inside the DataGridView at the top of the form.
Then I noticed something really weird after I clicked the “Add” button a few times. I can add one payment and everything works fine. But if I add two or more payments, things break – data changes made inside the controls at the bottom of the form are no longer reflected in the DataGridView at the top of the form. The weirdest thing is that everything still works perfectly for any original payments that were in the DataGridView when the form was first loaded and still works perfectly for the first new payment that I added. But for the second new payment and all new payments after that, changes to the detail controls at the bottom of the form are not reflected in the DataGridView at the top of the form. Doh!
Using the debugger I was able to confirm that my Payment object’s properties (like “Amount”) are always being changed correctly, regardless of whether the DataGridView reflects the changes or not.
Here’s the relevant code from my “New” constructor where my Order object is passed in as a parameter:
Me.PaymentsBindingSource.DataSource = mobjOrder.Payments
Here’s the relevant code from my “Add” button’s click handler:
mobjOrder.Payments.AddNew(mobjOrder)
There’s not a lot of code other than that – most of the functionality is being done automatically by Windows data-binding and the CSLA framework.
Does anybody have any suggestions about what is happening and how I can resolve this?
Thanks,
Jason
I've seen that problem as well. Like Andres said, it is about a non unique value. If the database already uses an int as a key, then I add a guid for identifying things locally while working with them. That has solved this problem for me.
Heath
I think you're right. I checked my Payment object - a new payment does not have an Id value until after the it saved for the first time (it gets the Id from the database insert). So the "GetIdValue" method is returning an empty string until the payment is saved once. I'm going to try assigning a temporary unique Id when a new payment is created so the "GetIdValue" method works correctly prior to saving and then change the Id to the real value after the save. I'll post again later and confirm whether that worked. I bet you've found the problem though. Thanks for the help!
Jason
Just wanted to confirm - that did fix the problem. Thanks again!
Jason
This is why I bring it up – soliciting feedback.
It does seem to be a recurring pain point for many people
though.
Rocky
From: xal
[mailto:cslanet@lhotka.net]
Sent: Thursday, September 13, 2007 4:36 PM
To: rocky@lhotka.net
Subject: Re: [CSLA .NET] Data Binding - DataGridView and Detail Controls
- Changes Not Reflected
Rocky,
Do you think it's really worth it? It means adding yet another field to the
base class that could be pottentially big (if you're aiming at guids).
Sometimes we move a lot of data through remoting and that could be a big perf
hit. I know: overriding it would keep it null so it might not be such a big
problem, but thenagain, you're opening the door for people to ignore that they
need to override it and that could create perf problems and usage problems that
would very difficult to track to GetIdValue().
Am I being too dramatic? Perhaps it's not such a big deal, but I'm sceptic when
it comes to changing something that creates an issue from time to time to
something else that could create new/undiscovered issues.
Andrés
I think these unique Id issues are a significant concern that probably warrants exploration.
I suspect that many people probably run into trouble with this......especially people like me who are forced to get their unique ids from a legacy app’s database and therefore don't have an real Id until after their object is saved for the first time.
I peeked inside the CSLA framework code, but could not come up with a good generic way of dealing with this unique Id issue from inside the framework that would cover all scenarios. Hopefully, one of you more experienced guys will eventually come up with a good solution.
I ended up generating and setting a temporary unique Id (global variable) while in "DataPortal_Create()". Then in "GetIdValue()", I check "IsNew()" to determine whether to return the value of the temporary id variable or the real id variable. I don't know if this is the best or most elegant solution, but so far it looks like this is going to work for me. If anyone has a better idea, please post it.
For what it’s worth, my current opinion is that these unique Id issues will probably have to be resolved by training rather than by tweaking the framework. The CSLA framework is pretty awesome and makes our life so much easier, but a framework can only do so much. At some point it’s up to all of us programmers to take the time to read the entire book, read this forum, and learn how to use the CSLA framework correctly.
Rocky….thanks so much for the framework, books, forums (especially your frequent participation)…..you’re awesome!
Jason
Hi Jason,
Can you send me the solution for this issue....Very Thank You~~
I ended up generating and setting a temporary unique Id (global variable) while in "DataPortal_Create()". Then in "GetIdValue()", I check "IsNew()" to determine whether to return the value of the temporary id variable or the real id variable.
Thank you for your kindly help
Edwin
That should be the solution... although if you're using a newer version of Csla, there's no need to override GetIdValue at all anymore.
Hi Andy,
Thank you for your answer.
I am using CSLA version 3.8.2. But I still got this issue...
My app got one window, which has one tab control on that.
On the tab control, I got 2 tab:
one tab is datagridview (that datasource is a bindingsource which is come from businesslistbase)(7 columns)
another tab is detailview(7 columns map to the columns in the datagridview)
Now when I load all data from db, the datagridview and detailview work very well (ex, move row, add row, change column value)
but after I save all the modified rows(New, Update rows) for the first time, something happened....
When I modify the detailview column (ex, StorerTypeID), and click the gridview tab, the (StorerTypeID) column in the gridview
didn't change its value... and when I click the (StorerTypeID) column in the gridview, then it refresh the new value!
Also, when I change the (StorerTypeID) column in the gridview, then click the detailview tab,
the (StorerTypeID) column in the detailview didn't change its value, even when I click that column, it still cann't change
to the new value which I just maintain in the gridview....
Could you give me some advise or some example for that ? Very Thanks.
Edwin
Copyright (c) Marimer LLC