iSeller Commerce
iSeller POS Retail
iSeller POS F&B
iSeller POS Express
Crosslight
WebUI
ClientUI
What's New
Download Trial
Web Solution
Mobile Solution
Enterprise Solution
Custom Development
Blog
Community
Latest Development Blogs
ForumPostTopic
Browse By Tag
I did not receive any answer the last four days searching for a result. In the meantime a found a solution myself. I don't know if this is the best design, but it works. For all others having the same problem, I'll show my solution here.
Looking through the samples I saw that in Page_Load the RootTable of the control is always empty. The sample just refills the the RootTable again, but the screen display remains on the old values. I don't fully understand this behaviour, or the reasons for this, but with this knowledge I could write a workaround.
My changes to my given sample in detail:
- In Page_Load remove the call to update the data from the user selections. (This will be done later.)
- In btnSave_Click add this call to update the data from the user selections.
- In Page_PreRender loop through all rows in RootTable and set row.Checked depending on the value in the column "Incl". Do this only if not in PostBack mode.
- In grid_InitializeRow remove the row.Checked=... statement as we moved this to Page_PreRender.
- In grid_initializeRow read the Default radio button selection by reading Request.Form("radioGroupDefaultModel"). This can only be read in case of a Postback.
- In grid_InitializeRow set the CHECKED status of the row depending on two criteria: a) If the value could be read (previous point) then compare the ID and set the value to CHECKED if it is this one b) This is for the initial load (no postback): Set the CHECKED status depending on the value of the column in the row.
Some comments:
We have two special things in this sample. One is that we use checkboxes to display a column. The WebGrid supports checkboxes, but those were not intended to display data. Because we only use one such column, we can use this feature. The problem is that in InitializeRow we just copied the value of the checkbox column to the checked status of the column. When we came into the postback, the selection was not preserved, because it was overwritten by this assignment. To fix this the assignment of the checked status is done in Page_PreRender, and only if not in PostBack mode.
The second special thing is that we have a database column Is_Default_Model. This will actually get rendered to a radio box button, so only one row can be selected. The rendering of the radiobox HTML in InitializeRow is ok. But we have to set the CHECKED value different. Previously we just set this status by looking at the database column. Now we do this only if not in PostBack mode, so only the first time the page loads. In InitializeRow we cannot access the PostBack flag, but we access the Request.Form("radioGroupDefaultModel") where we see what the user selected. If we have this value, we also know which radio button needs to be checked. If not, we're not in postback mode and can copy the checked status from the database row.
In Page_Load we cannot read the user selections, because the RootTable is empty - grid_InitializeDataSource was not called yet. So move this to the button click event. We don't need the data earlier anyway.
Let me know if you see anything to improve in this design.
I started a new thread for the remaining problem:
http://www.intersoftpt.com/Community/WebGrid/Grid-Resets-after-PostBack/
I just found the problem writing this thread. It looks like the step 10 comes between 9b and 11b, so the refresh of the data is at the wrong place. That's why after the postback the wrong data gets shown and in the internal structures it is correct.
This means that the design is wrong. How would it be correct, or what should I change here?
Still no fix available?
Hi Yudi, Thanks for your answer and all the hints.
Yes, the main problem was the call to grid.DataBind(). After removing this (and changing grid.DataSource to e.DataSource) the event InitializeDataSource was not been called anymore. So this problem is solved.
I couldn't find the sample PreserveCheckedRows you mentioned. By searching your support area, I found the link http://www.intersoftpt.com/Community/WebGrid/Retaining-Checkbox-with-Classic-Paging-Navigation/ and there was a sample you created. But unfortunately that download yields to a 404 page (not found).
Where should I find your two samples? I found the sample BindtoTraditionalDataSource only (maybe modified) in another thread here, but not the original sample itself. Maybe I didn't install sample or so? Are they on your website somewhere? At least they are not found when clicking on search. This is something you could improve and would help a lot. Also, searching for "RestoreRowSelection" just finds some threads, but not the documentation. Is this documented somewhere?
IsRowChecker is set to true on one column, so that's ok. RestoreRowSelection is not used anywhere. Do I need this? How would I use it?
The page was actually fully working before, I just had to add a small extension. Because of the bad design, a have actually rewritten most of the backend code. There was no InitializeDataSource event implemented previously for example. This is also the reason why I had this .DataBind code in there - I just moved it from the Page.Load event into there.
I added RestoreRowSelection to LayoutSettings, but this didn't change anything. I believe this is only for preserving the selected rows, so I don't need that. I just need to preserve the checked rows and that's dont automatically I think.
But I still have the problem that my selections get away. I'll try to create a sample, although this might take a few hours.
Thanks, Eric
Hi Handy,
Ok, so we just misunderstood each other. With full postback you meant any type of real postback while I thought of a full page reload. And with refresh you meant client-side refresh of the grid, while I meant a partly postback with Update Panel/AJAX. I just wanted to avoid this screen flickering when reloading the whole page - everything else is ok.
Regarding the fix/using events: So you don't see any other way to handle this. We'll wait for the bugfix in the WebGrid then. There is no special deadline for us. Is my assumption that it will take maximum 1-2 months correct? Please let me know in this thread when this problem is fixed.
Thanks,
Eric
Hello Handy,
You didn't say anything wrong. Everything ok.
Regarding the full postback problem: Where does the full postback come from? When I hide/remove columns and use freezing, this doesn't necessarily mean that not just the UpdatePanel gets refreshed. When I call RebindDataSource, I assumed only the UpdatePanel gets refreshed and not the whole page. I still think this should work. If it does not, why? I do understand that not only the grid's content needs to get updated, but also the things around the data etc. But for that reason I placed the UpdatePanel around it. If this is not enough, please let me know why.
Your previous sample does not work for one simple reason: You test if there is no data by checking the dropdown. In reality the dropdown selection is only an input parameter (filter value) for the data that comes from the database in InitializeDataSource. Therefore only there, or afterwards, we really know if there is data available or not. We cannot just test the dropdown. Think about the dropdown as selecting a US-State and the grid content as a list of customers. Perhaps in Utah there are no customers. So we cannot add code to test if dropdown=Utah then display "no data". We have to write the code in a way to test the data itself.
I thought of setting the width of these columns to zero instead of hiding them as a workaround. But this is not a clean solution either, because the user could resize them again or do an export where they reappear etc. If you have any other idea (like another event I could use), please let me know.
Fix: By removing the .Visible flag changes from PreRender to InitializeLayout, I could solve the main problem; it now doesn't crash anymore and we still can use the column freezing. The only problem that remains is that I now cannot hide the extra columns if there is no data, because this cannot be placed into PreRender or anywhere else after InitializeDataSource. This is not nice, but also not critical. If this bug can be fixed within the regular schedule in the next update (I assume within max. 1-2 months), I think this would be sufficient for us.
Regards,
Thanks for your reply.
You sound a little like you don't want to answer anymore. If this is the case, just let me know and don't answer anymore. But of course, if I don't get any answer about this bug in your product, this will influence our decision in buying upgrades or future versions from your company. Previously I always got an answer to any problem, even if it sometimes took several weeks and lots of emails to get resolved.
Questions about your last reply and open issues:
- What do you mean with "SelectedIndexChanged was not completely removed"? In your attachment above, the mentioned method is completely empty. Or did I overlook anything?
- Actually a full postback was not intended and only the WebGrid should refresh. I thought that works. Maybe my code or the sample has more problems. But let's focus on the initial problem.
Actually, the only important question that remains is this:
I want to set the column.Visible flag depending on the data I get. I get the data in InitializeDataSource event, as recommended. Afterwards I can access wg.RootTable to find out if there is data. You tell me that I cannot use the PreRender event to set the Visible flag because of a bug in WebGrid. So where should I set the column.Visible flag then? In InitializeLayout it is not possible, because InitializeDataSource has not been called yet, so we don't know to what value to set the flag. This is not a complex scenario. I don't need a new sample, just tell me what to do.
I need a working workaround for this bug.
Thanks for your modified sample. When I look at the code, you made the following changes:
- formatting changes
- remove xmlns from html tag
- move UpdatePanel, so that the dropdown ddlChoiceA is now within the UpdatePanel
- event handler for PreRender and ddlChoiceA_SelectedIndexChanged completely removed
- event handler InitializeLayout: call both SetColumnVisibility+SetColumnCaptions from there.
- SetColumnVisibility: set grdResult.LayoutSettings.AllowColumnFreezing flag
- SetColumnVisibility: detect empty resultset by detecting dropdown position instead of content
- SetColumnCaptions: add code to revert changes
I'd like to mention the following issues with your changes:
- You test if the Caption is B or X to set it to A. In reality, the caption contains something like "Current XXX value" or "Tomorrows XXX value" and XXX will get replaced to a word depending on the selection (let's say "red", "blue", "green"). It would be dangerous to add Replace code to detect XXX and all dropdown words to set it to the new word. These words might exist in the captions as well, if there is a caption like "Yesterday's XXX green selection" could get replaced to "Yesterday's red red selection" then. That's why I put this code into PreRender. That's the only place where this problem does not occur. A workaround for this issue would be to not use the Replace command and assign only the complete caption in the code (If ddl=3 then caption5="Yesterday's red green selection" etc.). Or just leave this caption change code in PreRender and the visibility setting in InitializeLayout, like I had it.
- You cannot test the dropdown selection to test if there is data available or not (to set the width etc.). Depending on the dropdown selection different data will be returned in InitializeDataSource (actually a stored procedure database call there). Therefore only the test I had (exactly one row and the first field equals a special text) would work. I know this is not 100% clean and robust code, because the same text could be returned by the database (at least in theory). But for normal cases this is good enough.
So where are your actual improvements?
- Set AllowColumnFreezing flag avoids the popup. Actually in the real project I had no such popup (for whatever reason), but I agree setting this would be a good idea anyway.
I first thought that InitializeLayout event will not get called every time and that's why it didn't refresh the visibility settings. But actually it does get called. The problem is that the data gets refreshed later (InitializeDataSource). Therefore, in InitializeLayout, we don't know yet if we should display all the columns or not (decision if resultset is empty or not). As I mentioned earlier, we cannot just test the dropdown selection. We have to look at the real data returned from InitializeDataSource. But if InitializeDataSource gets called after InitializeLayout, this doesn't help us and means we cannot set the Visibility flags in InitializeLayout.
One workaround would be to call the database in both events. But that is a) bad for performance, which is bad already now, and b) might cause unpredictable results if the database changes between the calls.
Another workaround would be to call the database in InitializeLayout and cache the data until needed in InitializeDataSource. But I think this is too complicated and unreliable (in case InitializeDataSource gets called without a prior call to InitializeLayout).
Any other idea for a workaround to this problem?
Ok, I created a new example. For unknown reasons, this example doesn't crash anymore, but this doesn't matter as it is to show the problems for the workaround.
There's also another bug in the example which causes a popup error message to appear (something with the freezing size). We can ignore that problem also, as it doesn't happen in the real code.
Please make sure to rename the two files after download (remove the "3" and the ".txt").
Issue: When you go to the PreRender event in the vb code and remove the call to SetColumnVisibility to avoid any call to set the .Visible flag in PreRender (in line 69; this is actually your workaround), then, when displaying the "no data" message, all additional columns will still get displayed instead of hidden.
or
Choose this if you're already a member of Intersoft Community Forum. You can link your OpenID account to your existing Intersoft Social ID.
Choose this if you don't have an Intersoft account yet. Your authenticated OpenID will be automatically linked to your new Intersoft account.
Enter your Wordpress Blogname