Hi,
I am working on a grid that allows the user to append new items (lines). When a user clicks in the first sell of a new row a form pops up where the user can select an item. This is done in the AfterCellActivate event. After selection, the selected item is added to the bound item an two cells are updated (serialnumber and name).
Now when the new row is leeved for example by click in another row or click in another control, the whole row is lost.
Before I displayed the select form in BeforePerfomAction with the NextCellByTab action. Here it worked fine.
What am I doing wrong in this new scenario? I also tried to Perform the CommitRow action manually but with not effect.
Kind regards
Patrick
Hi Patrick,
My guess is that it's something about the way in which you are adding the new row, but it's impossible to say, since you didn't mention exactly what you are doing there.
What kind of DataSource are you using here?
Are you adding the new row to the DataSource or to the grid? It generally makes more sense to add the row directly to the data source, unless you want the user to be able to cancel it.
If you can post a small sample project demonstrating the issue, I would be happy to take a look and I'm sure I could tell you what's wrong and how to fix it.
Hi Mike,
now I isolated the problem with a solution attached to this post. After having started just do the following:
The new row disappears.
The row remains as expected.
Can you see what I am doing wrong?
Kind regards and thanks for your helpPatrick
Okay, I see what's happening now. Your original post said that you were adding a row to the data source, but that's not what is happening. You are clicking on the TemplateAddRow. This causes the grid to add a new row to the data source, and then you are using that row, which has already been added, and populating it with data.
The row is getting removed because that's what is supposed to happen when there's a TemplateAddRow and the user hasn't made any changes to it.
When the user clicks into the TemplateAddRow the grid has to tell the data source to create a new row. This row is an AddNew row - it's not committed to the data source, yet. The grid needs to create this row immediately when the TemplateAddRow gets focus, because the grid needs to have the underlying row in order to function properly.
But if the user clicks into the TemplateAddRow and then leaves that row without making any changes, you don't want that row to be committed to the datasource. That would result in a blank row every time it happened, which does not make sense. So the grid automatically cancels this row when the user leaves the row without changing anything.
In your case, of course, the user is making changes to the row, but it's happening without the grid knowing about it.
So all you have to do here is tell the grid that changes have been made to the TemplateAddRow.
this.ultraGrid1.Rows.AddRowModifiedByUser = true;
Hi Mike
Was facing a similar issue - came across this thread.
If I add the row directly to the data source (datatable), I get the datarow object.
Whats the best way to get the corresponding ultragridrow object ?
Best Regards
Abhishek
Hi Abhishek,
It's much easier to get the data source row from the grid row than the other way around. To do that, you just use the row's ListObject property.
To go the other way, you can use the GetRowWithListIndex method on the rows collection.But this is tricky, because you have to know the ListIndex of the row in the data source. Also, you have to know which rows collection to use. This is easy if you are just displaying a flat list of data, but if your data is hierarchical, then it can get complicated.
So there has to be some factor in your real app that is different from the sample. I would try a process of elimination. Take a look at the events of the grid you are handling. Comment out the code in those events and see if the problem still occurs. Or put a breakpoint in each of the events and then reproduce the issue so you can see which of those events is firing and that might give you a hint which code is causing the issue.
Another approach you could take is to make a copy of your real app and try to reduce it down to the simplest possible app that still reproduces the issue. If you can narrow it down to something we could run, then we could look into it further. But without being able to reproduce the issue, there's no much more we can do.
The sample behaved very well on my machine as well. We tried with a number of variations on your project, and in each case the grid is behaving exactly as it should.
Basically we are using dataview to bind the grid and the rowfilter was being used. The phenomenon happens when UpdateData is called before setting the values in the row which would satisfy the rowfilter. Looking from the grid's perspective, I think this is how it should be.
Many thanks for the help!
I can't see any obvious reason why you would get those results. So I tried this out in a simple test project to see if I get the same behavior and I don't. I am attaching my test project here, but the results I get are like so:
row = Me.UltraGrid1.DisplayLayout.Bands(0).AddNew()
ListObject: System.Data.DataRowViewIsTemplateAddRow: FalseIsUnmodifiedTemplateAddRow: FalseIsAddRow: True
Me.UltraGrid1.UpdateData()
ListObject: System.Data.DataRowViewIsTemplateAddRow: FalseIsUnmodifiedTemplateAddRow: FalseIsAddRow: False
The row has a ListObject in both cases, just as I would expect. I am attaching my simple sample project here so you can try it out on your machine. If you get the same results as I do with my sample, then something else is happening in your real application which is causing the behavior. In that case, I would look at the events of the grid that you are handling and see if maybe some code in one of those events is the cause of the issue.
If my sample behaves the same way as your actual application on your machine, then that means you must be using a different version of the assemblies and maybe this is a bug in the version you have.
I am reproducing below the contents of the immediate window executed after the following statement:
gRow = myGrid.DisplayLayout.Bands(0).AddNew()
?gRow.ListObject{System.Data.DataRowView} System.Data.DataRowView: {System.Data.DataRowView}?gRow.IsTemplateAddRowFalse?gRow.IsUnmodifiedTemplateAddRowFalsemyGrid.UpdateData?gRow.ListObjectNothing?gRow.IsTemplateAddRowFalse?gRow.IsUnmodifiedTemplateAddRowFalse
First three statements are before calling UpdateData, next UpdateData is called and the same three statements are executed again.
Kindly Advise.
That's really weird. My best guess is that the row you have a reference to is not the new row. What must be happening is that when you commit the row (by calling UpdateData), the row you referenced becomes the new TemplateAddRow, and the real row that got added to the grid is a different row.
You could confirm this by checking:
gRow.IsTemplateAddRow and gRow.IsUnmodifiedTemplateAddRow
If either return true, then that would support my theory.
In theory, th "real new row should be the last row in the rows collection. So after you call UpdateData, you could re-get the row like this:
gRow = oGrid.Rows(oGrid.Rows.Count -1)
Now... I'm not sure if the TemplateAddRow counts against the row count. And it may also depend on whether that row is Fixed or not. So you might have to use -2 there instead of -1.