Hi,
My actual issue is exactly the same as the issue in this post: http://forums.infragistics.com/forums/p/33155/181098.aspx#181098. The only difference is that in the other forum post the user was binding to a calculated column being updated by a SQL Server call. That is NOT the case here ...
To recap quickly, I have an application that has multiple grids and win forms. A certain number of them bind to the same data table underneath. When I go to update a field in one of the win forms, I expect that same field in the grids to be updated as well since they are bound to the same data column. What I instead have to do is to click on another record in one of the grids and then click back to the record that was updated to see the change. I'm actually expecting that as soon as I tab off the field in the win form the same field in the grids is updated.
In the other forum post it was mentioned that this could be caused by the binding not sending a notification to the other controls to refresh. What would cause this to happen? What would be a fix that could be applied to correct this?
To answer some of the questions Mike had in the other forum post: The typical example in my application is an Order Qty field. If the user changes the value in the win form in the UltraNumericEditor control that is bound to the order quantity data column, the order quantity in the grid columns (also bound to the order quantity data column) do not update when the user tabs out of the UltraNumericEditor. The property I'm binding to for this field is the "Text" property.
Any help solving this issue would be greatly appreciated.
Thank you,
Steve
Hi Steve,
What kind of data source are you using here?
Let's take a simple example.. suppose I have a single grid on a form bound to some data source. When I do something (like click a button), I show a form with fields bound to the same data with individual controls like TextBoxes.
To make this work, the form I show would have to be bound to the same DataSource that the grid is using. And that DataSource has to be a robust data source that implement IBindingList. If it's just an IList, it won't work, because it will not notify the bound controls that things have changed.
Also, I'm pretty sure this won't work unless both the grid and the controls on the form have the same BindingContext. So you may need to set the BindingContext on the edit form to the same BindingContext that the grid is using. In fact, I'm not sure if just setting the BindingContext of the form will work. I think it will, because I'm pretty sure the controls on the form will get their BindingContext from their container... but you might have to set it on each control if the controls ar not directly on the form.
Hi Mike ... The data source I'm using is a dataset made up of temp-tables from a database. My forms and grids are bound to the same data source... In doing some more testing, it looks like the binding is working correctly as the underlying data tables get updated immediately when I change a value in the form or in the grid, and eventually the correct data appears in all the appropriate places ... However, I noticed that when I update a field on the form and then move my cursor so that it hovers over the same field in the grid, the grid refreshes and displays the updated value. It seems like there is a "lazy" refresh occurring for the grid. Is this a grid setting that you know of? ... Also, another curious thing I noticed is that the very first time I make a change in the form after bringing the application up, all the grids refresh and display the updated values correctly. But every subsequent change no longer appears immediately in the grids and the only way to get the changes to show is to hover over the field in the grid or click onto another record and then click back to the one I was editing. ... Any additional help you can give me to solve this mystery would be greatly appreciated.
Thanks!
I never had any doubt that the underlying data source is getting updated. You mentioned in your original post that mousing over the cell causes it to update. This is not surprising, since the cell goes and gets the value when it needs to paint.
So the problem here is that when you make the change on your form, your data source is not sending a notification to the grid that the change has been made and the grid does not know that it needs to refresh at that point.
This could be because of different BindingContexts, as I explained in my previous post.
This can also occur if your data source doesn't support IBindingList, but if you are using a DataSet, then that is clearly not the problem.
If you want to try to work around this, you can do so pretty easily by calling grid.Rows.Refresh(RefreshDisplay) any time a change occurs on your form.
Hi Mike,
Steve (thread author) and I are co-workers . We created a sample project to illustrate the problem Steve wrote about in this thread.
Notice in the image how field values are different. I changed the ID field at bottom and tabbed out. But the Grid continue to show the old value.
However, the very first time when I update the ID form field and tab out, it updates the Grid as expected. After that time, the Grid no longer refreshes on tabbing out out of ID form field . I have to either hover over the Grid row I just updated or click on another row to make it refresh.
You can see this in a very simple example I attaching. We would appreciate if you could try it and let us know what is causing this behavior.
Thank you very much!
PS; Since we are using an older version of Infragistics, I have built the solution with "copy local" to help you build quickly.
I tried your sample and I get the same results, even using the latest version of NetAdvantage.
However, this does not appear to be an issue with the Infragistics controls. I tried replacing the UltraWinGrid with the Microsoft DataGridView and the UltraTextEditors with the Microsoft TextBox controls and I get the same results. Just to be extra careful, I remove all Infragistics controls from the project and I still get the same results.
So I don't know why this is happening, but it appears to be a bug or some strange quirk in the DotNet BindingManager.
I'm attaching my modified sample here so you can check it out. I recommend reporting the problem to Microsoft or checking a more general MS or DataBinding forum. I can't believe that no one else has ever encountered a similar problem before.
We are still working through this issue and have had some success using BindingSource and BindingContext to sync updates between the form and the grid. I do have a question about something we are doing in regards to getting updates made in the grid to appear in the form, and whether you feel this is the most expedient way of handling that situation.
In order to get the form controls (i.e. textboxes, etc) to update when the grid is updated, we use KeyActionMapping on the grid that does a CommitRow action when you press a certain key such as Enter or Tab. Here is what the code looks like:
this.ultraGrid1.KeyActionMappings.Add( new GridKeyActionMapping(Keys.Tab,UltraGridAction.CommitRow,0,UltraGridState.InEdit ,0,0));
The question is why do you think the CommitRow action necessary in order for the update done in the grid to simultaneously appear in the related form control? Are there any disadvantages to using CommitRow in this regard? Is there a grid property that we can use to do basically what this KeyActionMapping/CommitRow code is doing? Our concern is that we are creating code for something that the grid might already do on it's own, and we'd like to avoid that and implement the grid functionality properly. ... If there is a property that controls this that we can use then hopefully that same property exists for the form controls as well, as we'd like to have the same solution no matter which direction the updates are going (form to grid or grid to form). Let me know what you think ...
Thank you!
If you just want to commit the changes to the current row in the grid, then all you have to do is call Update on the row or UpdateData on the grid.
The grid will, by default, automatically commit the changes when you leave the row or lose focus on the grid. But if you click on something else on the form, such as a toolbar button, that does not take focus, then you need to make sure you manually call one of the above-mentioned methods to commit the changes.
Hi Mike ... The mapping does work. What we are looking for is to have the grid and the form update when the user exits a grid cell or form control. We know that the CommitRow happens when you click on another row. However in our app we don't want to have to force the user to click on another row and then click back on the row they updated just to see the changes display. For the mapping, when the user exits the cell or control with what ever key we've mapped to do a CommitRow it updates the display the same way as if you have clicked on another row. We were just wonderinig if using the mapping is necesary or if there was an equivalent way (i.e. a property) in the grid and in a form control to have it do a CommitRow when the user tabs out or clicks out of the cell/control they are updating. Using the mapping seems a bit forced and thought maybe there is something in the grid functionality that would do this for us without implementing the mapping code ...
Since I don't know what the original issue is or what it's cause was, I'm afraid I don't have much of a guess on the matter.
Moving from one row to another in the grid already commits the row to the underlying DataSource of the grid and that will happen before the CommitRow maping gets called, since you are adding your new mapping to the end of the collection. So I really can't see how your mapping could be having any effect at all. It will not even get triggered until the grid has already moved the focus to the next row.
Are you sure that this mapping actually does something? If so, then I must be wrong about some part of this. Either that or committing a row with no changes is somehow forcing the BindingManager to do some sort of refresh or update. But that seems very strange and unlikely.
You could try trapping the BeforePerformAction event on the grid and trap for actions like NextRowByTab and PrevRowByTab and then call PerformAction(CommitRow) or grid.ActiveRow.Update in there to see if that has any effect.