This is a migrated thread and some comments may be shown as answers.

SaveLayout/LoadLayout Documentation

10 Answers 431 Views
GridView
This is a migrated thread and some comments may be shown as answers.
erwin
Top achievements
Rank 1
Veteran
Iron
erwin asked on 23 Dec 2008, 12:04 PM
Hello,

I'm currently playing around with the SaveLayout LoadLayout Methods of RadGridView.
The basic Idea of these functions is quite interesting.
 
How are situations handled where the definition of the grid or datasource during LoadLayout is slightly different from the time the layout was saved?
What's the expected behaviour if number, header, relative position and/or data types of columns change, or if the grid itself gets resized?

I could not find comprehensive documentation about these functions.

Regards
Erwin

10 Answers, 1 is accepted

Sort by
0
Nick
Telerik team
answered on 23 Dec 2008, 04:57 PM
Hi erwin,

Thank you for your feedback. We will provide documentation soon. In the mean time, I am copying a ticket reply that contains some useful information:

I'll try to explain explain how Save/LoadLayout works since Q2 SP1.

SaveLayout persist all grid properties, similar to ComponentCodeDomSerializaer that VS designer uses, following the same rules - i.e. it uses properties serialization metadata (attributes) like DefaultValue, DesignerSerializationVisibility TypeConverter and others. There are few excluded properties though, like RadGridView.Name, ThemeName and DataSource, DataMember of all GridViewTemplates in the hierarchy. Those properties concern the runtime behavior of the grid and were causing various problems when serializing/deserializing.

As it comes to deserialization, there are some new things to consider:
  • The GridColumns collection is merged upon deserialization. The columns that are present in the grid instance, which call LoadLayout, are mapped to those found in the xml file by the UniqueName property and then deserialized. Columns are reordered according to the xml-layout definition. The extra Columns found in the xml file that are not present in the original collection are added to the collection. No columns are deleted/recreated in the original collection. This is important, because column objects may contain references to other objects/components, e.g. the combo-column may have a DataSource and so on. Since Q2 SP2 loading layout will not break this column's behavior.
  • Similar to the column's updating logic, LoadLayout will not delete any existing GridViewTemplates when used in hierarchy mode. But RadGridView will load templates' properties in the same order they appear in the xml file. In other words, for best results LoadLayout expects the same grid hierarchy structure as the on that was used with SaveLayout. Nevertheless LoadLayout should not fail in other cases. Instead, extra GridViewTemplate definition found in the xml will be added to the corresponding ChildTemplates collection.
Here is a sample unit-test code that I use to validate some parts of the logic of Save/LoadLayout methods. It may help you clarify how we think this feature should work:


[TestMethod] 
        public void TestPeristGridColumns() 
        { 
            //Create grid test instance and set some properties, columns, etc 
            //later on we will test if all properties and structure are persisted to another grid instance 
            RadGridView gridView = new RadGridView(); 
 
            gridView.Size = new System.Drawing.Size(100, 100); 
            gridView.Behavior.ShowItemToolTips = true
            gridView.DataMember = "MasterDataMemeber"
            gridView.Location = new Point(10, 11); 
 
            GridViewTextBoxColumn textBoxColumn = new GridViewTextBoxColumn("field1"); 
            textBoxColumn.Width = 155; 
            textBoxColumn.SortOrder = RadSortOrder.Descending;             
            gridView.MasterGridViewTemplate.Columns.Add(textBoxColumn); 
 
            gridView.MasterGridViewTemplate.FilterExpressions.Add(new FilterExpression("field1", FilterExpression.BinaryOperation.AND, GridKnownFunction.StartsWith, new object[] { "a" })); 
 
            ConditionalFormattingObject formattingObject = new ConditionalFormattingObject("Green", ConditionTypes.Equal, "France"""false); 
            formattingObject.CellForeColor = Color.Red; 
            formattingObject.CellBackColor = Color.Blue; 
 
            textBoxColumn.ConditionalFormattingObjectList.Add(formattingObject); 
 
            GridViewDecimalColumn decimalColumn = new GridViewDecimalColumn("field2"); 
            decimalColumn.Width = 200; 
            gridView.MasterGridViewTemplate.Columns.Add(decimalColumn); 
 
            GridViewTemplate childTemplate = new GridViewTemplate(gridView); 
            childTemplate.DataMember = "TestMember"
            childTemplate.GroupBy = "field3 group by field3"
            childTemplate.HorizontalScrollState = ScrollState.AlwaysShow; 
            gridView.MasterGridViewTemplate.ChildGridViewTemplates.Add(childTemplate); 
 
            childTemplate.Columns.Add(new GridViewTextBoxColumn("field3")); 
 
            string output = null
 
            using (StringWriter stringWriter = new StringWriter()) 
            { 
                using (XmlWriter writer = new XmlTextWriter(stringWriter)) 
                { 
                    gridView.SaveLayout(writer); 
                } 
                output = stringWriter.ToString(); 
                Console.WriteLine(output); 
            } 
 
            Assert.IsNotNull(output); 
 
            //now deserialize 
            gridView = new RadGridView(); 
 
            //create only 1 column this time, to test column merging 
            gridView.DataMember = "MasterDataMemeber"
            gridView.Columns.Add(new GridViewDecimalColumn("field2")); 
 
            //child templates should match 
            childTemplate = new GridViewTemplate(gridView); 
            childTemplate.DataMember = "TestMember"
            gridView.MasterGridViewTemplate.ChildGridViewTemplates.Add(childTemplate); 
 
            using (StringReader reader = new StringReader(output)) 
            { 
                using (XmlTextReader textReader = new XmlTextReader(reader)) 
                { 
                    gridView.LoadLayout(textReader); 
                } 
            } 
 
            Assert.AreEqual(new Point(10, 11), gridView.Location); 
            Assert.AreEqual("MasterDataMemeber", gridView.DataMember); 
            Assert.AreEqual(true, gridView.Behavior.ShowItemToolTips); 
            Assert.AreEqual(new System.Drawing.Size(100, 100), gridView.Size); 
             
            //test columns deserialization and correct ordering 
            Assert.AreEqual(2, gridView.Columns.Count);  
            Assert.AreEqual(typeof(GridViewTextBoxColumn), gridView.Columns[0].GetType()); 
            Assert.AreEqual(155, gridView.Columns[0].Width); 
            Assert.AreEqual(RadSortOrder.Descending, gridView.Columns[0].SortOrder); 
 
            Assert.AreEqual(1, gridView.Columns[0].ConditionalFormattingObjectList.Count); 
            Assert.AreEqual(Color.Red, gridView.Columns[0].ConditionalFormattingObjectList[0].CellForeColor); 
 
            Assert.AreEqual(typeof(GridViewDecimalColumn), gridView.Columns[1].GetType()); 
            Assert.AreEqual(200, gridView.Columns[1].Width); 
 
            //tests filtering 
            Assert.AreEqual("(([" + gridView.Columns[0].FieldAlias + "] LIKE 'a%'))", gridView.MasterGridViewTemplate.FilterExpressions[0].ToString()); 
 
            //test grouping and hierarchy deserialization 
            Assert.AreEqual(1, gridView.MasterGridViewTemplate.ChildGridViewTemplates.Count); 
            Assert.AreEqual("TestMember", gridView.MasterGridViewTemplate.ChildGridViewTemplates[0].DataMember); 
            Assert.AreEqual(1, gridView.MasterGridViewTemplate.ChildGridViewTemplates[0].Columns.Count); 
            Assert.AreEqual(ScrollState.AlwaysShow, childTemplate.HorizontalScrollState); 
            Assert.AreEqual("field3", gridView.MasterGridViewTemplate.ChildGridViewTemplates[0].Columns[0].UniqueName); 
        } 

Let me know if you have any other questions.

Kind regards,
Nick
the Telerik team

Check out Telerik Trainer, the state of the art learning tool for Telerik products.
0
Dragoljub
Top achievements
Rank 1
answered on 07 Jan 2009, 10:39 AM
Hi,

One question about the layout saving and loading functionality.

Why do you include Location and Size of the grid? I know that data is conventionally considered "layout", but in the case of the grid, it should not be.

For me, the layout of the grid means: how the data is sorted, how it is filtered, which columns are visible, by which column the data is grouped, and maybe even the "design time" data such as: allow add, allow delete, read-only, selection mode and similar functional properties. But the position and size should be something that is determined at design time (or run-time if the grid is anchored or docked). If you made a poll, I bet 95% of people would vote like me, because the context where one would use this feature is similar to my case.
0
erwin
Top achievements
Rank 1
Veteran
Iron
answered on 07 Jan 2009, 10:46 PM

There is an undocumented way to specify exactly what gets serialized to xml.
I got the workaround on the answer to a support ticket, therefore I don't publish it here.

Either open a ticket with telerik, or maybe they publish the workaround here.

I agree with your opinion about the size and location properties. In my examples, I think they are ignored on load.
At least I have not experienced unexpected behaviour when loading layouts into re-sized grids. However, all my grids use fill docking to their container (usually table layout panel) which probably overrides size and location. If your grids are resized/moved on load layout, you might try to fill dock them into a container (panel etc.).

Regards
Erwin


0
Dragoljub
Top achievements
Rank 1
answered on 07 Jan 2009, 11:20 PM
It was docked! And then I discovered that the grouping panel was not showing columns by which the data was grouped WHEN the grid is docked and inside a WindowsFormsHost (in a WPF application). So the workaround that is currently in place is to use anchors on all sides.

I know it's just XML and it's easy to remove unwanted data before persisting the XML, I just didn't get a chance to do it yet.
0
erwin
Top achievements
Rank 1
Veteran
Iron
answered on 08 Jan 2009, 03:13 PM
The Telerik approach does not involve direct manipulation of the .xml but rather using a customized Serializer object which is IMHO much more elegant. Trouble is that this is not documented yet.

Erwin
0
Nick
Telerik team
answered on 09 Jan 2009, 10:44 AM
Hello Dragoljub,

Thank you for your feedback. We are glad that you found a way to workaround this issue. We are going to remove serialization of Size, Location and Dock properties for 2008 Q3 SP2 which is to be released the week of 19th this month.

If you are anxious to customize serialization, I can send you some sample code. We are, though, adding a few new serialization APIs in RadGridView in order to make it more convenient for you.

Sincerely yours,
Nick
the Telerik team

Check out Telerik Trainer, the state of the art learning tool for Telerik products.
0
Dragoljub
Top achievements
Rank 1
answered on 09 Jan 2009, 01:53 PM
Thanks for the tip. I can wait for the week after the 19th.

I also must report another strange problem we had related to SaveLayout and LoadLayout and updating to a new version, although I don't see how you can fix it, because I don't have much details. The whole application got frozen soon after the LoadLayout was called. You only had to click on a column header, try filtering, or try grouping or open& try to close column chooser. It was solved finally by removing the grid from the form and adding it again (but first the toolbox items also had to be removed and added manually to point to the new version, the installer didn't do that!). I guess it was some properties stored in the .Designer.vb source file, but the stored layout xml was deleted as well, so maybe that was part of the solution too.

The column chooser still made problems - when it's opened and you try to close it, the app gets frozen. The only clue we have to this problem is that it appears intermitently WHEN there are grouping columns. One theory I have is that your code for drawing (and managing drag& drop operations) within the area where grouped columns are shown (in the header of the grid) is causing this problem. We also encountered that bug where that area remains empty if you set grid's Dock property to Fill inside a WPF application. That is a reproducable issue and earlier I have submitted it as a support ticket using a different account. Maybe you can start from there. These other issues are harder to reproduce, I'm still not able to create a small and simple repro project.
0
Nick
Telerik team
answered on 12 Jan 2009, 09:58 AM
Hello Dragoljub,

Thank you for writing us back and reporting the issues. We are going to check and fix them if we manage to reproduce the behavior. Please send us a sample project if you manage to do so because it will help us a lot. Do not hesitate to write me back if you have more questions.

Regards,
Nick
the Telerik team

Check out Telerik Trainer, the state of the art learning tool for Telerik products.
0
KawaUser
Top achievements
Rank 2
answered on 28 Jul 2017, 08:12 PM
I am trying to load a layout from saved resource file.   It has been saved from the grid designer and then added as a resource to the project.  Is this possible?
0
Dimitar
Telerik team
answered on 31 Jul 2017, 11:29 AM
Hi  Derrick,

Yes, this is possible. Detailed information is available here:
I hope this will be useful. Let me know if you have additional questions.

Best wishes,
Dimitar
the Telerik team

Instantly find answers to your questions on the new Telerik Support Portal.
Check out the tips for optimizing your support resource searches.
Tags
GridView
Asked by
erwin
Top achievements
Rank 1
Veteran
Iron
Answers by
Nick
Telerik team
Dragoljub
Top achievements
Rank 1
erwin
Top achievements
Rank 1
Veteran
Iron
KawaUser
Top achievements
Rank 2
Dimitar
Telerik team
Share this question
or