[System] UriKind.RelativeOrAbsolute workaround.
[mono.git] / mcs / class / System.Web / Test / System.Web.UI.WebControls / BoundFieldTest.cs
1 //
2 // Tests for System.Web.UI.WebControls.BoundFieldTest.cs
3 //
4 // Author:
5 //      Yoni Klein (yonik@mainsoft.com)
6 //
7 //
8 // Copyright (C) 2005 Novell, Inc (http://www.novell.com)
9 //
10 // Permission is hereby granted, free of charge, to any person obtaining
11 // a copy of this software and associated documentation files (the
12 // "Software"), to deal in the Software without restriction, including
13 // without limitation the rights to use, copy, modify, merge, publish,
14 // distribute, sublicense, and/or sell copies of the Software, and to
15 // permit persons to whom the Software is furnished to do so, subject to
16 // the following conditions:
17 //
18 // The above copyright notice and this permission notice shall be
19 // included in all copies or substantial portions of the Software.
20 //
21 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
22 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
23 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
24 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
25 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
26 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
27 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
28
29
30
31 using System;
32 using System.Collections.Generic;
33 using System.Text;
34 using System.Web;
35 using System.Web.UI;
36 using System.Web.UI.WebControls;
37 using System.IO;
38 using System.Drawing;
39 using System.Collections;
40 using System.Collections.Specialized;
41 using Image = System.Web.UI.WebControls.Image;
42 using NUnit.Framework;
43 using System.Globalization;
44 using MonoTests.SystemWeb.Framework;
45 using MonoTests.stand_alone.WebHarness;
46
47
48
49 namespace MonoTests.System.Web.UI.WebControls
50 {
51         class EncodingTest
52         {
53                 public override string ToString ()
54                 {
55                         return "<EncodingTest>&";
56                 }
57         }
58
59         class PokerBoundField : BoundField
60         {
61                 public Button bindbutoon;
62
63                 public PokerBoundField () {
64                         TrackViewState ();
65                         bindbutoon = new Button ();
66                         bindbutoon.DataBinding += new EventHandler (OnDataBindField);
67                 }
68
69
70                 public StateBag StateBag {
71                         get { return base.ViewState; }
72                 }
73
74                 public bool DoSupportsHtmlEncode {
75                         get {
76                                 return base.SupportsHtmlEncode;
77                         }
78                 }
79
80                 public void DoCopyProperties (DataControlField newField) {
81                         base.CopyProperties (newField);
82                 }
83
84                 public DataControlField DoCreateField () {
85                         return base.CreateField ();
86                 }
87
88                 public string DoFormatDataValue (object dataValue, bool encode) {
89                         return this.FormatDataValue (dataValue, encode);
90                 }
91
92                 public object DoGetDesignTimeValue () {
93                         return base.GetDesignTimeValue ();
94                 }
95
96                 public object DoGetValue (Control controlContainer) {
97                         return base.GetValue (controlContainer);
98                 }
99
100                 public void DoInitializeDataCell (DataControlFieldCell cell, DataControlRowState rowState) {
101                         base.InitializeDataCell (cell, rowState);
102                 }
103
104                 public void DoOnDataBindField (object sender, EventArgs e) {
105                         base.OnDataBindField (sender, e);
106                 }
107
108                 public Control GetControl {
109                         get { return base.Control; }
110                 }
111
112                 public object DoSaveViewState ()
113                 {
114                         return SaveViewState ();
115                 }
116         }
117
118
119         [Serializable]
120         [TestFixture]
121         public class BoundFieldTest
122         {
123                 [TestFixtureSetUp]
124                 public void SetUp ()
125                 {
126                         WebTest.CopyResource (GetType (), "BoundField_Bug646505.aspx", "BoundField_Bug646505.aspx");
127                         WebTest.CopyResource (GetType (), "BoundField_Bug646505.aspx.cs", "BoundField_Bug646505.aspx.cs");
128                 }
129
130                 [Test (Description="Bug 646505")]
131                 public void BoundField_Bug646505 ()
132                 {
133 #if NET_4_0
134                         string originalHtml = "<div>\n\t<table cellspacing=\"0\" rules=\"all\" border=\"1\" id=\"gridView\" style=\"border-collapse:collapse;\">\n\t\t<tr>\n\t\t\t<th scope=\"col\">&nbsp;</th><th scope=\"col\">&nbsp;</th>\n\t\t</tr><tr>\n\t\t\t<td><a href=\"javascript:__doPostBack(&#39;gridView$ctl02$ctl00&#39;,&#39;&#39;)\">Update</a>&nbsp;<a href=\"javascript:__doPostBack(&#39;gridView&#39;,&#39;Cancel$0&#39;)\">Cancel</a></td><td><input name=\"gridView$ctl02$ctl02\" type=\"text\" value=\"False\" /></td>\n\t\t</tr><tr>\n\t\t\t<td><a href=\"javascript:__doPostBack(&#39;gridView&#39;,&#39;Edit$1&#39;)\">Edit</a></td><td>False</td>\n\t\t</tr>\n\t</table>\n</div>\n";
135 #else
136                         string originalHtml = "<div>\n\t<table cellspacing=\"0\" rules=\"all\" border=\"1\" id=\"gridView\" style=\"border-collapse:collapse;\">\n\t\t<tr>\n\t\t\t<th scope=\"col\">&nbsp;</th><th scope=\"col\">&nbsp;</th>\n\t\t</tr><tr>\n\t\t\t<td><a href=\"javascript:__doPostBack('gridView$ctl02$ctl00','')\">Update</a>&nbsp;<a href=\"javascript:__doPostBack('gridView','Cancel$0')\">Cancel</a></td><td><input name=\"gridView$ctl02$ctl02\" type=\"text\" value=\"False\" /></td>\n\t\t</tr><tr>\n\t\t\t<td><a href=\"javascript:__doPostBack('gridView','Edit$1')\">Edit</a></td><td>False</td>\n\t\t</tr>\n\t</table>\n</div>\n";
137 #endif
138                         WebTest t = new WebTest ("BoundField_Bug646505.aspx");
139                         t.Run ();
140
141                         FormRequest fr = new FormRequest (t.Response, "form1");
142                         fr.Controls.Add ("__EVENTTARGET");
143                         fr.Controls.Add ("__EVENTARGUMENT");
144                         fr.Controls ["__EVENTTARGET"].Value = "gridView";
145                         fr.Controls ["__EVENTARGUMENT"].Value = "Edit$0";
146                         t.Request = fr;
147                         string pageHtml = t.Run ();
148                         string renderedHtml = HtmlDiff.GetControlFromPageHtml (pageHtml);
149
150                         HtmlDiff.AssertAreEqual (originalHtml, renderedHtml, "#A1");
151                 }
152                 
153                 [Test]
154                 public void BoundField_DefaultProperty () {
155                         PokerBoundField bf = new PokerBoundField ();
156                         Assert.AreEqual ("!", PokerBoundField.ThisExpression, "StaticThisExpression");
157                         Assert.AreEqual ("", bf.DataField, "DataField");
158                         Assert.AreEqual ("", bf.DataFormatString, "DataFormatString");
159                         Assert.AreEqual ("", bf.HeaderText, "HeaderText");
160                         Assert.AreEqual (true, bf.HtmlEncode, "HtmlEncode");
161                         Assert.AreEqual ("", bf.NullDisplayText, "NullDisplayText");
162                         Assert.AreEqual (false, bf.ReadOnly, "ReadOnly");
163
164                         //Protected 
165                         Assert.AreEqual (true, bf.DoSupportsHtmlEncode, "SupportsHtmlEncode");
166                 }
167
168                 [Test]
169                 public void BoundField_DefaultPropertyNotWorking () {
170                         PokerBoundField bf = new PokerBoundField ();
171                         Assert.AreEqual (false, bf.ApplyFormatInEditMode, "ApplyFormatInEditMode");
172                         Assert.AreEqual (true, bf.ConvertEmptyStringToNull, "ConvertEmptyStringToNull");
173                 }
174
175                 [Test]
176                 public void BoundField_AssignProperty () {
177                         PokerBoundField bf = new PokerBoundField ();
178                         bf.ConvertEmptyStringToNull = false;
179                         Assert.AreEqual (false, bf.ConvertEmptyStringToNull, "ConvertEmptyStringToNull");
180                         bf.DataField = "test";
181                         Assert.AreEqual ("test", bf.DataField, "DataField");
182                         bf.DataFormatString = "test";
183                         Assert.AreEqual ("test", bf.DataFormatString, "DataFormatString");
184                         bf.HeaderText = "test";
185                         Assert.AreEqual ("test", bf.HeaderText, "HeaderText");
186                         bf.HtmlEncode = false;
187                         Assert.AreEqual (false, bf.HtmlEncode, "HtmlEncode");
188                         bf.NullDisplayText = "test";
189                         Assert.AreEqual ("test", bf.NullDisplayText, "NullDisplayText");
190                         bf.ReadOnly = true;
191                         Assert.AreEqual (true, bf.ReadOnly, "ReadOnly");
192                 }
193
194                 [Test]
195                 public void BoundField_AssignPropertyNotWorking () {
196                         PokerBoundField bf = new PokerBoundField ();
197                         bf.ApplyFormatInEditMode = true;
198                         Assert.AreEqual (true, bf.ApplyFormatInEditMode, "ApplyFormatInEditMode");
199                 }
200
201                 [Test]
202                 public void BoundField_ExtractValuesFromCell () {
203                         PokerBoundField bf = new PokerBoundField ();
204                         OrderedDictionary dictionary = new OrderedDictionary ();
205                         DataControlFieldCell cell = new DataControlFieldCell (null);
206                         cell.Text = "test";
207                         bf.ExtractValuesFromCell (dictionary, cell, DataControlRowState.Normal, true);
208                         Assert.AreEqual (1, dictionary.Count, "ExtractValuesFromCellCount");
209                         Assert.AreEqual ("test", dictionary [0].ToString (), "ExtractValuesFromCellValue");
210                 }
211
212                 [Test]
213                 public void BoundField_Initialize () {
214                         // This method initilize to private fields in a base class DataControlField 
215                         // Always return false
216                         PokerBoundField bf = new PokerBoundField ();
217                         Control control = new Control ();
218                         control.ID = "test";
219                         bool res = bf.Initialize (true, control);
220                         // Assert.AreEqual (false, res, "InitializeResult");
221                         Assert.AreEqual ("test", bf.GetControl.ID, "InitializeControl");
222                 }
223
224                 [Test]
225                 public void BoundField_InitializeCell () {
226                         PokerBoundField bf = new PokerBoundField ();
227                         // Header text
228                         DataControlFieldCell cell = new DataControlFieldCell (null);
229                         bf.HeaderText = "headertext";
230
231                         bf.InitializeCell (cell, DataControlCellType.Header, DataControlRowState.Edit, 1);
232                         Assert.AreEqual ("headertext", cell.Text, "InitializeCellHeaderText");
233                         // Empty header text
234                         bf.HeaderText = "";
235                         bf.InitializeCell (cell, DataControlCellType.Header, DataControlRowState.Edit, 1);
236                         Assert.AreEqual ("&nbsp;", cell.Text, "InitializeCellEmpty");
237
238                         bf.HeaderText = "headertext";
239                         // Header image url not empty
240                         bf.HeaderImageUrl = "headerurl";
241                         bf.InitializeCell (cell, DataControlCellType.Header, DataControlRowState.Edit, 1);
242                         if (cell.Controls [0] is Image) {
243                                 Image image = (Image) cell.Controls [0];
244                                 Assert.AreEqual ("headerurl", image.ImageUrl, "InitializeCellHeaderImageUrl");
245                         }
246                         else {
247                                 Assert.Fail ("Header Image dos not created");
248                         }
249
250                         // Footer empty
251                         bf.FooterText = "footertext";
252                         bf.InitializeCell (cell, DataControlCellType.Footer, DataControlRowState.Edit, 1);
253                         Assert.AreEqual ("footertext", cell.Text, "InitializeCellFooterText");
254                         bf.FooterText = "";
255                         bf.InitializeCell (cell, DataControlCellType.Footer, DataControlRowState.Edit, 1);
256                         Assert.AreEqual ("&nbsp;", cell.Text, "InitializeCellFooterEmpty");
257                 }
258
259                 [Test]
260                 public void BoundField_ValidateSupportsCallback () {
261                         //This method has been implemented as an empty method           
262                 }
263
264                 [Test]
265                 public void BoundField_SortExpression () {
266                         // Sorting enable = true , link button must be created
267                         PokerBoundField bf = new PokerBoundField ();
268                         // Header text
269                         DataControlFieldCell cell = new DataControlFieldCell (null);
270
271                         bf.HeaderImageUrl = "";
272                         bf.SortExpression = "a";
273                         bf.HeaderText = "sortbutton";
274                         bf.Initialize (true, new Control ());    // _base._sortingenable set to true
275                         bf.InitializeCell (cell, DataControlCellType.Header, DataControlRowState.Edit, 1);
276                         if (cell.Controls [0] is Button) { // mono
277                                 Button lb = (Button) cell.Controls [0];
278                                 Assert.AreEqual ("Sort", lb.CommandName, "InitializeCellHeaderSortButtonCommand");
279                                 Assert.AreEqual ("a", lb.CommandArgument, "InitializeCellHeaderSortButtonArgument");
280                                 Assert.AreEqual ("sortbutton", lb.Text, "InitializeCellHeaderSortButtonText");
281
282                         }
283                         else if (cell.Controls [0] is LinkButton) { // .net
284                                 LinkButton lb = (LinkButton) cell.Controls [0];
285                                 Assert.AreEqual ("Sort", lb.CommandName, "InitializeCellHeaderSortButtonCommand");
286                                 Assert.AreEqual ("a", lb.CommandArgument, "InitializeCellHeaderSortButtonArgument");
287                                 Assert.AreEqual ("sortbutton", lb.Text, "InitializeCellHeaderSortButtonText");
288
289                         }
290                         else {
291                                 Assert.Fail ("Sort button does not created");
292                         }
293                 }
294
295
296                 [Test]
297                 public void BoundField_CopyProperties () {
298                         PokerBoundField bf = new PokerBoundField ();
299                         BoundField copy = new BoundField ();
300                         // Look not working property
301                         // bf.ApplyFormatInEditMode = true;
302                         bf.ConvertEmptyStringToNull = true;
303                         bf.DataField = "test";
304                         bf.DataFormatString = "test";
305                         bf.HtmlEncode = true;
306                         bf.NullDisplayText = "test";
307                         bf.ReadOnly = true;
308                         bf.DoCopyProperties (copy);
309                         // Look not working property
310                         // Assert.AreEqual (true, copy.ApplyFormatInEditMode, "ApplyFormatInEditMode");
311                         Assert.AreEqual (true, copy.ConvertEmptyStringToNull, "ConvertEmptyStringToNull");
312                         Assert.AreEqual ("test", copy.DataField, "DataField");
313                         Assert.AreEqual ("test", copy.DataFormatString, "DataFormatString");
314                         Assert.AreEqual (true, copy.HtmlEncode, "HtmlEncode");
315                         Assert.AreEqual ("test", copy.NullDisplayText, "NullDisplayText");
316                         Assert.AreEqual (true, copy.ReadOnly, "ReadOnly");
317                 }
318
319                 [Test]
320                 public void BoundField_CreateField () {
321                         PokerBoundField bf = new PokerBoundField ();
322                         BoundField newfield = (BoundField) bf.DoCreateField ();
323                         Assert.IsNotNull (newfield, "CreateField");
324                 }
325
326                 [Test]
327                 public void BoundField_FormatDataValue () {
328                         string result;
329                         PokerBoundField bf = new PokerBoundField ();
330
331                         bf.NullDisplayText = "NullDisplayText";
332                         result = bf.DoFormatDataValue (null, false);
333                         Assert.AreEqual ("NullDisplayText", result, "FormatDataValueNullDataValue");
334
335                         result = bf.DoFormatDataValue ("test", true);
336                         Assert.AreEqual ("test", result, "FormatDataValueTextDataValue");
337
338                         result = bf.DoFormatDataValue ("", true);
339                         Assert.AreEqual ("NullDisplayText", result, "FormatEmptyDataValue");
340
341                         bf.DataFormatString = "-{0,8:G}-";
342                         result = bf.DoFormatDataValue (10, false);
343                         Assert.AreEqual ("-      10-", result, "FormatDataValueWithFormat");
344
345                         bf.DataFormatString = "-{0:X}-";
346                         result = bf.DoFormatDataValue (10, true);
347                         Assert.AreEqual ("-A-", result, "FormatDataValueWithFormatAndHtmlEncode");
348
349                         bf.DataFormatString = "-{0:X}-";
350                         result = bf.DoFormatDataValue (10, false);
351                         Assert.AreEqual ("-A-", result, "FormatDataValueWithFormatAndNoHtmlEncode");
352
353                         bf.HtmlEncodeFormatString = false;
354                         bf.DataFormatString = "-{0:X}-";
355                         result = bf.DoFormatDataValue (10, true);
356                         Assert.AreEqual ("-10-", result, "NoHtmlEncodeFormatString_HtmlEncode");
357
358                         bf.DataFormatString = "-{0:X}-";
359                         result = bf.DoFormatDataValue (10, false);
360                         Assert.AreEqual ("-A-", result, "NoHtmlEncodeFormatString_NoHtmlEncode");
361                 }
362
363                 [Test]
364                 public void HtmlEncodeFormatString ()
365                 {
366                         string formatString = "<script>alert ('{0}');</script>"; 
367                         var bf = new PokerBoundField ();
368
369                         Assert.IsTrue (bf.HtmlEncodeFormatString, "#A1-2");
370                         Assert.IsTrue (bf.HtmlEncode, "#A1-2");
371                         Assert.IsTrue (bf.DoSupportsHtmlEncode, "#A1-3");
372
373                         bf.DataFormatString = formatString;
374 #if NET_4_0
375                         Assert.AreEqual ("&lt;script&gt;alert (&#39;&lt;test&gt;&#39;);&lt;/script&gt;", bf.DoFormatDataValue ("<test>", true), "#A2");
376 #else
377                         Assert.AreEqual ("&lt;script&gt;alert ('&lt;test&gt;');&lt;/script&gt;", bf.DoFormatDataValue ("<test>", true), "#A2");
378 #endif
379                         Assert.AreEqual (String.Format (formatString, "<test>"), bf.DoFormatDataValue ("<test>", false), "#A3");
380
381                         bf.HtmlEncodeFormatString = false;
382                         Assert.AreEqual ("<script>alert ('&lt;test&gt;');</script>", bf.DoFormatDataValue ("<test>", true), "#A4");
383
384                         var ec = new EncodingTest ();
385                         bf.HtmlEncodeFormatString = true;
386 #if NET_4_0
387                         Assert.AreEqual ("&lt;script&gt;alert (&#39;&lt;EncodingTest&gt;&amp;&#39;);&lt;/script&gt;", bf.DoFormatDataValue (ec, true), "#A4");
388 #else
389                         Assert.AreEqual ("&lt;script&gt;alert ('&lt;EncodingTest&gt;&amp;');&lt;/script&gt;", bf.DoFormatDataValue (ec, true), "#A4");
390 #endif
391                 }
392
393                 [Test]
394                 public void BoundField_GetDesignTimeValue () {
395                         string result;
396                         PokerBoundField bf = new PokerBoundField ();
397                         result = (string) bf.DoGetDesignTimeValue ();
398                         Assert.AreEqual ("Databound", result, "GetDesignTimeValue");
399                 }
400
401                 [Test]
402                 [ExpectedException(typeof(HttpException), ExpectedMessage="A data item was not found in the container. The container must either implement IDataItemContainer, or have a property named DataItem.")]
403                 public void BoundField_GetValueNull () {
404                         PokerBoundField bf = new PokerBoundField ();
405                         SimpleSpreadsheetRow ds = new SimpleSpreadsheetRow (0, null);
406                         bf.DataField = PokerBoundField.ThisExpression;
407                         string result = (string) bf.DoGetValue (ds);
408                 }
409
410                 [Test]
411                 public void BoundField_GetValue () {
412                         PokerBoundField bf = new PokerBoundField ();
413                         SimpleSpreadsheetRow ds = new SimpleSpreadsheetRow (0, "test");
414                         bf.DataField = PokerBoundField.ThisExpression;
415                         string result = (string) bf.DoGetValue (ds);
416                         Assert.AreEqual ("test", result, "GetValueFromIDataItemContainer");
417                 }
418
419                 [Test]
420                 public void BoundField_GetValueDataItem () {
421                         PokerBoundField bf = new PokerBoundField ();
422                         ControlWithDataItem ds = new ControlWithDataItem ("test");
423                         bf.DataField = PokerBoundField.ThisExpression;
424                         string result = (string) bf.DoGetValue (ds);
425                         Assert.AreEqual ("test", result, "GetValueFromIDataItemContainer");
426                 }
427
428                 [Test]
429                 public void BoundField_InitializeDataCell () {
430                         PokerBoundField bf = new PokerBoundField ();
431                         bf.HeaderText = "headertest";
432                         DataControlFieldCell cell = new DataControlFieldCell (null);
433                         DataControlRowState state = DataControlRowState.Edit;
434                         Assert.AreEqual (0, cell.Controls.Count, "InitializeDataCellControlsBeforeInit");
435                         bf.DoInitializeDataCell (cell, state);
436                         Assert.AreEqual (1, cell.Controls.Count, "InitializeDataCellControlsAfterInit");
437                 }
438
439                 [Test]
440                 [ExpectedException (typeof (HttpException))]
441                 public void BoundField_OnDataBindFieldExeption () {
442                         PokerBoundField bf = new PokerBoundField ();
443                         bf.bindbutoon.DataBind ();
444
445                 }
446
447                 [Test]
448                 [ExpectedException (typeof (HttpException))]
449                 public void BoundField_GetValueExeption () {
450                         PokerBoundField bf = new PokerBoundField ();
451                         bf.DoGetValue (null);
452                 }
453
454                 [Test]
455                 [Category ("NunitWeb")]
456                 public void BoundField_NullValueRender ()
457                 {
458                         string html = new WebTest (PageInvoker.CreateOnLoad (new PageDelegate (BasicRenderTestInit))).Run ();
459                         string orightml = "<div>\r\n\t<table cellspacing=\"0\" rules=\"all\" border=\"1\" style=\"border-collapse:collapse;\">\r\n\t\t<tr>\r\n\t\t\t<th scope=\"col\">&nbsp;</th><th scope=\"col\">&nbsp;</th>\r\n\t\t</tr><tr>\r\n\t\t\t<td>Norway</td><td>Norway</td>\r\n\t\t</tr><tr>\r\n\t\t\t<td>Sweden</td><td>Sweden</td>\r\n\t\t</tr><tr>\r\n\t\t\t<td>EMPTY</td><td>&nbsp;</td>\r\n\t\t</tr><tr>\r\n\t\t\t<td>Italy</td><td>Italy</td>\r\n\t\t</tr>\r\n\t</table>\r\n</div>";
460                         html = HtmlDiff.GetControlFromPageHtml (html);
461                         HtmlDiff.AssertAreEqual (orightml, html, "NullValueRender");
462                 }
463
464                 public static void BasicRenderTestInit (Page p)
465                 {
466                         ArrayList myds = new ArrayList ();
467                         myds.Add (new myds_data ("Norway"));
468                         myds.Add (new myds_data ("Sweden"));
469                         myds.Add (new myds_data (""));
470                         myds.Add (new myds_data ("Italy"));
471
472                         BoundField bf = new BoundField ();
473                         bf.DataField = "Field1";
474                         bf.NullDisplayText = "EMPTY";
475
476                         BoundField bf2 = new BoundField ();
477                         bf2.DataField = "Field1";
478
479                         GridView GridView1 = new GridView();
480                         GridView1.AutoGenerateColumns = false;
481                         GridView1.Columns.Add (bf);
482                         GridView1.Columns.Add (bf2);
483                         GridView1.DataSource = myds;
484                         GridView1.DataBind ();
485
486                         LiteralControl lcb = new LiteralControl (HtmlDiff.BEGIN_TAG);
487                         LiteralControl lce = new LiteralControl (HtmlDiff.END_TAG);
488
489                         p.Form.Controls.Add (lcb);
490                         p.Form.Controls.Add (GridView1);
491                         p.Form.Controls.Add (lce);
492                 }
493
494                 class myds_data
495                 {
496                         string _s = "";
497                         public myds_data (string s)
498                         {
499                                 _s = s;
500                         }
501
502                         public string Field1
503                         {
504                                 get { return _s; }
505                         }
506                 }
507
508                 
509                 class ControlWithDataItem : Control
510                 {
511                         readonly object _data;
512                         public ControlWithDataItem (object data) {
513                                 _data = data;
514                         }
515
516                         public object DataItem {
517                                 get {
518                                         return _data;
519                                 }
520                         }
521                 }
522
523                 public class SimpleSpreadsheetRow : TableRow, IDataItemContainer
524                 {
525                         private object data;
526                         private int _itemIndex;
527
528                         public SimpleSpreadsheetRow (int itemIndex, object o) {
529                                 data = o;
530                                 _itemIndex = itemIndex;
531                         }
532
533                         public virtual object Data {
534                                 get {
535                                         return data;
536                                 }
537                         }
538
539                         object IDataItemContainer.DataItem {
540                                 get {
541                                         return Data;
542                                 }
543                         }
544
545                         int IDataItemContainer.DataItemIndex {
546                                 get {
547                                         return _itemIndex;
548                                 }
549                         }
550
551                         int IDataItemContainer.DisplayIndex {
552                                 get {
553                                         return _itemIndex;
554                                 }
555                         }
556                 }
557         }
558 }