public override object ConvertTo(ITypeDescriptorContext context, CultureInfo culture, object value, System.Type destinationType)
        {
            if (destinationType == null)
            {
                throw new ArgumentNullException("destinationType");
            }
            if (!(value is TableLayoutSettings) || !(destinationType == typeof(string)))
            {
                return(base.ConvertTo(context, culture, value, destinationType));
            }
            TableLayoutSettings settings = value as TableLayoutSettings;
            StringBuilder       output   = new StringBuilder();
            XmlWriter           writer   = XmlWriter.Create(output);

            writer.WriteStartElement("TableLayoutSettings");
            writer.WriteStartElement("Controls");
            foreach (TableLayoutSettings.ControlInformation information in settings.GetControlsInformation())
            {
                writer.WriteStartElement("Control");
                writer.WriteAttributeString("Name", information.Name.ToString());
                writer.WriteAttributeString("Row", information.Row.ToString(CultureInfo.CurrentCulture));
                writer.WriteAttributeString("RowSpan", information.RowSpan.ToString(CultureInfo.CurrentCulture));
                writer.WriteAttributeString("Column", information.Column.ToString(CultureInfo.CurrentCulture));
                writer.WriteAttributeString("ColumnSpan", information.ColumnSpan.ToString(CultureInfo.CurrentCulture));
                writer.WriteEndElement();
            }
            writer.WriteEndElement();
            writer.WriteStartElement("Columns");
            StringBuilder builder2 = new StringBuilder();

            foreach (ColumnStyle style in (IEnumerable)settings.ColumnStyles)
            {
                builder2.AppendFormat("{0},{1},", style.SizeType, style.Width);
            }
            if (builder2.Length > 0)
            {
                builder2.Remove(builder2.Length - 1, 1);
            }
            writer.WriteAttributeString("Styles", builder2.ToString());
            writer.WriteEndElement();
            writer.WriteStartElement("Rows");
            StringBuilder builder3 = new StringBuilder();

            foreach (RowStyle style2 in (IEnumerable)settings.RowStyles)
            {
                builder3.AppendFormat("{0},{1},", style2.SizeType, style2.Height);
            }
            if (builder3.Length > 0)
            {
                builder3.Remove(builder3.Length - 1, 1);
            }
            writer.WriteAttributeString("Styles", builder3.ToString());
            writer.WriteEndElement();
            writer.WriteEndElement();
            writer.Close();
            return(output.ToString());
        }
        public override object ConvertTo(ITypeDescriptorContext context, CultureInfo culture, object value, Type destinationType)
        {
            if (value is TableLayoutSettings && (destinationType == typeof(string)))
            {
                TableLayoutSettings tableLayoutSettings = value as TableLayoutSettings;

                StringBuilder xmlStringBuilder = new StringBuilder();
                XmlWriter     xmlWriter        = XmlWriter.Create(xmlStringBuilder);
                xmlWriter.WriteStartElement("TableLayoutSettings");

                //
                // write controls
                //
                xmlWriter.WriteStartElement("Controls");

                foreach (TableLayoutSettings.ControlInformation c in tableLayoutSettings.GetControlsInformation())
                {
                    if (c.Name is null)
                    {
                        throw new InvalidOperationException(SR.TableLayoutSettingsConverterNoName);
                    }

                    xmlWriter.WriteStartElement("Control");
                    xmlWriter.WriteAttributeString("Name", c.Name.ToString());
                    xmlWriter.WriteAttributeString("Row", c.Row.ToString(CultureInfo.CurrentCulture));
                    xmlWriter.WriteAttributeString("RowSpan", c.RowSpan.ToString(CultureInfo.CurrentCulture));

                    xmlWriter.WriteAttributeString("Column", c.Column.ToString(CultureInfo.CurrentCulture));
                    xmlWriter.WriteAttributeString("ColumnSpan", c.ColumnSpan.ToString(CultureInfo.CurrentCulture));

                    xmlWriter.WriteEndElement();
                }
                xmlWriter.WriteEndElement(); // end Controls

                //
                // write columns
                //
                xmlWriter.WriteStartElement("Columns");
                StringBuilder columnStyles = new StringBuilder();
                foreach (ColumnStyle colStyle in tableLayoutSettings.ColumnStyles)
                {
                    columnStyles.AppendFormat("{0},{1},", colStyle.SizeType, colStyle.Width);
                }
                if (columnStyles.Length > 0)
                {
                    columnStyles.Remove(columnStyles.Length - 1, 1);
                }
                xmlWriter.WriteAttributeString("Styles", columnStyles.ToString());
                xmlWriter.WriteEndElement(); // end columns

                //
                // write rows
                //
                xmlWriter.WriteStartElement("Rows");
                StringBuilder rowStyles = new StringBuilder();
                foreach (RowStyle rowStyle in tableLayoutSettings.RowStyles)
                {
                    rowStyles.AppendFormat("{0},{1},", rowStyle.SizeType, rowStyle.Height);
                }
                if (rowStyles.Length > 0)
                {
                    rowStyles.Remove(rowStyles.Length - 1, 1);
                }
                xmlWriter.WriteAttributeString("Styles", rowStyles.ToString());
                xmlWriter.WriteEndElement(); // end Rows

                xmlWriter.WriteEndElement(); // end TableLayoutSettings

                xmlWriter.Close();
                return(xmlStringBuilder.ToString());
            }
            return(base.ConvertTo(context, culture, value, destinationType));
        }
        public void TableLayoutSettings_RoundTripAndExchangeWithNet()
        {
            string netBlob;

            using (var tableLayoutPanel = new TableLayoutPanel
            {
                Name = "table",
                CellBorderStyle = TableLayoutPanelCellBorderStyle.OutsetDouble,
                ColumnCount = 3,
                RowCount = 2
            })
            {
                tableLayoutPanel.ColumnStyles.Add(new ColumnStyle(SizeType.Percent, 50));
                tableLayoutPanel.ColumnStyles.Add(new ColumnStyle(SizeType.Percent, 50));
                tableLayoutPanel.ColumnStyles.Add(new ColumnStyle(SizeType.Percent, 50));
                tableLayoutPanel.RowStyles.Add(new RowStyle(SizeType.Absolute, 20));
                tableLayoutPanel.RowStyles.Add(new RowStyle(SizeType.Absolute, 30));

                var button00_10 = new Button()
                {
                    Name = "button00_10"
                };
                tableLayoutPanel.Controls.Add(button00_10, 0, 0);
                tableLayoutPanel.SetColumnSpan(button00_10, 2);
                var label20_21 = new Label()
                {
                    Name = "label20_21"
                };
                tableLayoutPanel.Controls.Add(label20_21, 2, 0);
                tableLayoutPanel.SetRowSpan(label20_21, 2);
                tableLayoutPanel.Controls.Add(new RadioButton()
                {
                    Name = "radioButton01"
                }, 0, 1);
                tableLayoutPanel.Controls.Add(new CheckBox()
                {
                    Name = "checkBox11"
                }, 1, 1);

                netBlob = BinarySerialization.ToBase64String(tableLayoutPanel.LayoutSettings as TableLayoutSettings);
            }

            // ensure we can deserialise NET serialised data and continue to match the payload
            ValidateResult(netBlob);
            // ensure we can deserialise NET Fx serialised data and continue to match the payload
            ValidateResult(ClassicTableLayoutSettings);

            void ValidateResult(string blob)
            {
                TableLayoutSettings result = BinarySerialization.EnsureDeserialize <TableLayoutSettings>(blob);

                Assert.NotNull(result);
                Assert.True(result.IsStub);                                                 // This class is not associated with an owner control.
                Assert.Equal(TableLayoutPanelCellBorderStyle.None, result.CellBorderStyle); // This property is not serialized.
                Assert.NotNull(result.LayoutEngine);
                // These values will be accessible when the owner is set.
                Assert.Throws <NullReferenceException>(() => result.CellBorderWidth);
                Assert.Throws <NullReferenceException>(() => result.ColumnCount);
                Assert.Throws <NullReferenceException>(() => result.GrowStyle);
                Assert.Throws <NullReferenceException>(() => result.RowCount);
                Assert.Equal(3, result.ColumnStyles.Count);
                Assert.Equal(2, result.RowStyles.Count);
                Assert.Equal(SizeType.Percent, result.ColumnStyles[0].SizeType);
                Assert.Equal(SizeType.Percent, result.ColumnStyles[1].SizeType);
                Assert.Equal(SizeType.Percent, result.ColumnStyles[2].SizeType);
                Assert.Equal(SizeType.Absolute, result.RowStyles[0].SizeType);
                Assert.Equal(20, result.RowStyles[0].Height);
                Assert.Equal(30, result.RowStyles[1].Height);

                List <ControlInformation> controls = result.GetControlsInformation();

                ValidateControlInformation("button00_10", 0, 0, 2, 1, controls[0]);
                ValidateControlInformation("label20_21", 2, 0, 1, 2, controls[1]);
                ValidateControlInformation("radioButton01", 0, 1, 1, 1, controls[2]);
                ValidateControlInformation("checkBox11", 1, 1, 1, 1, controls[3]);

                void ValidateControlInformation(string name, int column, int row, int columnSpan, int rowSpan, ControlInformation control)
                {
                    Assert.Equal(name, control.Name);
                    Assert.Equal(column, control.Column);
                    Assert.Equal(row, control.Row);
                    Assert.Equal(columnSpan, control.ColumnSpan);
                    Assert.Equal(rowSpan, control.RowSpan);
                }
            }
        }