I have removed a column from my datasource. But the users have the column saved in their previous old layout preferences files which they saved earlier. As suggested in other posts I have loaded a new UltraGridLayout object with that file. I now want to remove the specific column from that layout by doing
layout.Bands[0].Columns.Remove(column);
But it is returning an error for can't change/remove bound column. The layout object is still not bound or loaded to any grid. How can I remove that specific column from the layout so that when I load it to the grid then it does not return a error?
Hi,
I think you probably have to load the layout into the grid first and then remove the column. At that point, the grid will know that there is no datasource column mapped to the column and it will treat it like an unbound column. I think that will work, although I haven't tried it out. If it doesn't work, please let me know and we will look into it further.
Also I noticed that the grid does not throw any exception for the old xml. Does the grid handle this by itself the different column names or can it throw some exception in some other case.
I'm afraid you lost me on both counts. If the column does not exist in the grid once you load that layout into the grid, then what's the problem? There's no need to remove it - it won't be there, anyway.
Also... I don't understand what you mean about an exception. Why would there be an exception? What kind of exception are you expecting?
Hi Mike,
See there are to different problems. First is I want to make sure if in future one of my column changes then how do I handle the formatting of the grid. What happens in such cases is:- lets say we have 4 columns ABCD we have some formatting for them saved in xml by the user. Now we have changed column B to E. Then the default formatting which I apply just before loading the layout is lost for the column E. And if I do the default formatting after loading then the user's formatting is overridden. So how do approach it.
The other problem is when I am applying formatting on the grid then the datafilters on editors in columns are disabled and the data is not filtered. I have tried to handle it by assigning the datafilter after loading the layout but this causes it modify the data just after loading the grid which is visible if there is very large data.
Okay...
Puneet Earan said:See there are to different problems. First is I want to make sure if in future one of my column changes then how do I handle the formatting of the grid. What happens in such cases is:- lets say we have 4 columns ABCD we have some formatting for them saved in xml by the user. Now we have changed column B to E. Then the default formatting which I apply just before loading the layout is lost for the column E. And if I do the default formatting after loading then the user's formatting is overridden. So how do approach it.
There's no easy way to change the layout such that column E now occupies the same position and properties as column B did. You could do it manually, I suppose, by loading the layout into memory and storing it, then loading the layout into the grid and then manually copying all of the properties of B in the stored layout into column E in the grid. This would be a lengthy and difficult process, though, and I certainly wouldn't want to have to write that code.
Another possible approach would be to try to modify the XML and change the "B" to an "E". But I wouldn't recommend this either. I've never tried it and quite frankly I don't have any idea what kind of complications this might entail in terms of hooking up the related objects.
The approach that I have taken in the past is that whenever I make a change to my application that might cause the saved layouts on the user's machine to be invalid, I simply don't load them. The layout simply reverts to the default when the user runs the application and they have to rearrange things back the way they want them. This is not ideal, but realistically, there's no way you could possibly anticipate every possible case in order to merge one layout with another.
The way I achieved this is that I saved the layout into a stream and the first element in the stream is a version number. In the application I define a constant that represents the layout version. Any time I change something in the layout, I bump this version number. Whenever the layout is saved, this version number is the first thing into the stream. When I load the layout, I read the stream and load up the version number first. If the versions match, I load the layout. If they don't, I just skip and don't load anything.
Puneet Earan said:The other problem is when I am applying formatting on the grid then the datafilters on editors in columns are disabled and the data is not filtered. I have tried to handle it by assigning the datafilter after loading the layout but this causes it modify the data just after loading the grid which is visible if there is very large data.
DataFilters are not saved with the layout. They cannot be, because the DataFilter is an interface. So it's some object that implements that interface, and there's no way for the grid to serialize that object. Even if the object is serializable, the grid doesn't save it, because you could be implementing that interface on any object, just as the Form, and it would cause an infinite recursive loop for the grid to serialize the form, which contains the grid.
Typically, you would assign editors and DataFilters inside the InitializeLayout event.
I don't know what you mean when you say that assigning the DataFilters is changing the data. That sounds like a problem with your DataFilter, but I can't really guess without a lot more information and probably a sample.
ok thank you Mike.
Hi Al,
Yeah, I'm having some trouble understanding how that tiered approach would work.
I mean, if the end-user has a save layout then loading that should be sufficient and you wouldn't even need any of your base layout or other changes, because they would already be included in the saved layout. That shouldn't cause a problem, but it's also redundant.
The approach I've taken in some applications is to store the layout along with a version number. Basically instead of saving the layout directly to a file, you save it to a stream and you preface the stream with some other data, like a version number.
When the application loads, you load the stream and look at the version number. If it's the same, no problem, go ahead and load the layout. If it's different than the application version, then you know something in the application has changed, and it might be a good idea to revert to the default layout and don't try to load the end-users customizations. This is not ideal, of course, since the end-user loses their changes. But you only bump the version number when know the old layouts aren't go to work, like when you added or removed a column. And they only have to recreate their layouts when they install a new version with a new version number.
This is, in fact, the approach we use with our own AppStylist.
understood. my strategy for layouts in my application may be a little far fetched. meaning, i create one default layout by allowing the user to re-arrange columns , formats, groups one time. I put a shortcut key for the user to save that layout as a default (to xml). then i take that file and deploy it with the application. (all categories). unfortunately i think this method is flawed because i make runtime changes to the layout after i call loadfromxml() for certain things. so it becomes more of a base layout than default.
And to make it worse, i allow all users to make changes to their own changes and automatically save the layouts to their personal drives when they close the app(on formclose()).
i've been finding problems with this tiered layout approach. especially when adding new fields to my DTO. BUT FOR THE MOST PART FIELDS ARE NEVER CHANGED OR REMOVED.
not sure where to take it from here. if i change any layouts in this tiered approach, the layouts are affected or unaffected downstream.
An older layout file should be able to load into the newer version of the grid. The only time the layout will fail is when the grid can't match up the structure in the layout with the structure of the grid. For example, if the band s have changed (name or number) or the columns have changed (name, datatype).
There's no way to get involved in the process of loading a layout. If the grid won't load it, there's no way to make it work. You could load the layout into a Layout variable (instead of directly into the grid) and then try to manually copy everything in that layout into the grid's DisplayLayout, but it's essentially all or nothing.
If your columns and bands have not changed and the layout is not loading correctly, then something may be wrong there. I'd have to see an example of exactly what's happening in order to say more.
hi Mike, i've run into a similar problem. i have a displayout that doesn't work with users' existing saved layouts. merging them looks like a mess. i would be fine with them keeping their layouts as they are. let their layouts override my changes (it's up to them if they want to discard their own layouts) i just don't want to break their layouts from loading.
if i were to assert that columns are never removed or changed (name) is there a way to do this? some users have several custom layouts and this would be really rough for all of us. loading the new and old displaylayouts into memory and copying sounds like an idea.
thanks for any info.
AL