[asp.net] Fix for bug #646505. BoundField must not assume the sender of the OnDataBin...
authorMarek Habersack <grendel@twistedcode.net>
Fri, 29 Oct 2010 00:25:25 +0000 (02:25 +0200)
committerMarek Habersack <grendel@twistedcode.net>
Fri, 29 Oct 2010 00:25:25 +0000 (02:25 +0200)
mcs/class/System.Web/Makefile
mcs/class/System.Web/System.Web.UI.WebControls/BoundField.cs
mcs/class/System.Web/Test/System.Web.UI.WebControls/BoundFieldTest.cs
mcs/class/System.Web/Test/mainsoft/NunitWebResources/BoundField_Bug646505.aspx [new file with mode: 0644]
mcs/class/System.Web/Test/mainsoft/NunitWebResources/BoundField_Bug646505.aspx.cs [new file with mode: 0644]

index f1644f2ae8b6db170387fc2a39446e92e4d09145..438c0e9747e6bccc577bcb0591544b313f163210 100644 (file)
@@ -232,7 +232,9 @@ TEST_RESOURCE_FILES = \
        Test/mainsoft/NunitWebResources/CheckBoxField_Bug595568_6.aspx \
        Test/mainsoft/NunitWebResources/CheckBoxField_Bug595568_7.aspx \
        Test/mainsoft/NunitWebResources/GridView_Bug595567.aspx \
-       Test/mainsoft/NunitWebResources/CheckBoxList_Bug600415.aspx
+       Test/mainsoft/NunitWebResources/CheckBoxList_Bug600415.aspx \
+       Test/mainsoft/NunitWebResources/BoundField_Bug646505.aspx \
+       Test/mainsoft/NunitWebResources/BoundField_Bug646505.aspx.cs
 
 RESX_DIST =  resources/TranslationResources.resx
 ifneq (1, $(FRAMEWORK_VERSION_MAJOR))
index ffd3c8ba939e923546884d040f51bf7ecf87a5db..8f067835b7533cb476d588ed2649d532d8e51654 100644 (file)
@@ -249,21 +249,33 @@ namespace System.Web.UI.WebControls
                
                protected virtual void OnDataBindField (object sender, EventArgs e)
                {
-                       Control cell = (Control) sender;
-                       Control controlContainer = cell.BindingContainer;
+                       Control container = (Control) sender;
+                       Control controlContainer = container.BindingContainer;
                        if (!(controlContainer is INamingContainer))
                                throw new HttpException ("A DataControlField must be within an INamingContainer.");
                        object val = GetValue (controlContainer);
+                       TextBox box = sender as TextBox;
 
-                       if (cell.Controls.Count > 0) {
-                               TextBox box = (TextBox) cell.Controls [0];
-                               if (ApplyFormatInEditMode)
-                                       box.Text = FormatDataValue (val, SupportsHtmlEncode && HtmlEncode);
-                               else
-                                       box.Text = val != null ? val.ToString() : NullDisplayText;
+                       if (box == null) {
+                               var cell = sender as DataControlFieldCell;
+                               if (cell != null) {
+                                       ControlCollection controls = cell.Controls;
+                                       int ccount = controls != null ? controls.Count : 0;
+                                       if (ccount == 1)
+                                               box = controls [0] as TextBox;
+                                       if (box == null) {
+                                               cell.Text = FormatDataValue (val, SupportsHtmlEncode && HtmlEncode);
+                                               return;
+                                       }
+                               }
                        }
+
+                       if (box == null)
+                               throw new HttpException ("Bound field " + DataField + " contains a control that isn't a TextBox.  Override OnDataBindField to inherit from BoundField and add different controls.");
+                       if (ApplyFormatInEditMode)
+                               box.Text = FormatDataValue (val, SupportsHtmlEncode && HtmlEncode);
                        else
-                               ((DataControlFieldCell)cell).Text = FormatDataValue (val, SupportsHtmlEncode && HtmlEncode);
+                               box.Text = val != null ? val.ToString() : NullDisplayText;
                }
                
                protected override DataControlField CreateField ()
index 2035112d53fbcaf66637920044d92094e17ef948..44e784a38199ec786ad05b67c7afaf0114aa40a8 100644 (file)
@@ -121,6 +121,36 @@ namespace MonoTests.System.Web.UI.WebControls
        [TestFixture]
        public class BoundFieldTest
        {
+               [TestFixtureSetUp]
+               public void SetUp ()
+               {
+                       WebTest.CopyResource (GetType (), "BoundField_Bug646505.aspx", "BoundField_Bug646505.aspx");
+                       WebTest.CopyResource (GetType (), "BoundField_Bug646505.aspx.cs", "BoundField_Bug646505.aspx.cs");
+               }
+
+               [Test (Description="Bug 646505")]
+               public void BoundField_Bug646505 ()
+               {
+#if NET_4_0
+                       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";
+#else
+                       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";
+#endif
+                       WebTest t = new WebTest ("BoundField_Bug646505.aspx");
+                       t.Run ();
+
+                       FormRequest fr = new FormRequest (t.Response, "form1");
+                       fr.Controls.Add ("__EVENTTARGET");
+                       fr.Controls.Add ("__EVENTARGUMENT");
+                       fr.Controls ["__EVENTTARGET"].Value = "gridView";
+                       fr.Controls ["__EVENTARGUMENT"].Value = "Edit$0";
+                       t.Request = fr;
+                       string pageHtml = t.Run ();
+                       string renderedHtml = HtmlDiff.GetControlFromPageHtml (pageHtml);
+
+                       HtmlDiff.AssertAreEqual (originalHtml, renderedHtml, "#A1");
+               }
+               
                [Test]
                public void BoundField_DefaultProperty () {
                        PokerBoundField bf = new PokerBoundField ();
diff --git a/mcs/class/System.Web/Test/mainsoft/NunitWebResources/BoundField_Bug646505.aspx b/mcs/class/System.Web/Test/mainsoft/NunitWebResources/BoundField_Bug646505.aspx
new file mode 100644 (file)
index 0000000..f827504
--- /dev/null
@@ -0,0 +1,21 @@
+<%@ Page Language="C#" AutoEventWireup="true" CodeFile="BoundField_Bug646505.aspx.cs" Inherits="MonoBoundFieldCompatibilityIssue._Default" %>
+
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head runat="server">
+    <title></title>
+</head>
+<body>
+    <form id="form1" runat="server">
+    <div>
+        <%= MonoTests.stand_alone.WebHarness.HtmlDiff.BEGIN_TAG %><asp:GridView runat="server" ID="gridView" 
+            OnInit="OnGridViewInit" 
+            AutoGenerateColumns="False"
+            AutoGenerateEditButton="True"
+            OnRowUpdating="OnGridViewEditCancelling"
+            OnRowCancelingEdit="OnGridViewEditCancelling" 
+            OnRowEditing="OnGridViewRowEditing" /><%= MonoTests.stand_alone.WebHarness.HtmlDiff.END_TAG %>
+    </div>
+    </form>
+</body>
+</html>
diff --git a/mcs/class/System.Web/Test/mainsoft/NunitWebResources/BoundField_Bug646505.aspx.cs b/mcs/class/System.Web/Test/mainsoft/NunitWebResources/BoundField_Bug646505.aspx.cs
new file mode 100644 (file)
index 0000000..95a8bfc
--- /dev/null
@@ -0,0 +1,59 @@
+using System;
+using System.Web.UI.WebControls;
+
+namespace MonoBoundFieldCompatibilityIssue
+{
+       public partial class _Default : System.Web.UI.Page
+       {
+               #region [ -- Custom Column Definition -- ]
+
+               /// <summary>
+               /// Custom Column for the GridView
+               /// </summary>
+               class CustomColumn : BoundField
+               {
+                       protected override void InitializeDataCell (DataControlFieldCell cell, DataControlRowState rowState)
+                       {
+                               if ((rowState & DataControlRowState.Edit) != DataControlRowState.Normal) {
+                                       TextBox textBox = new TextBox ();
+                                       cell.Controls.Add (textBox);
+                                       textBox.DataBinding += OnDataBindField;
+                               } else
+                                       base.InitializeDataCell (cell, rowState);
+                       }
+               }
+
+               #endregion
+
+               protected void Page_Load (object sender, EventArgs e)
+               {
+                       if (IsPostBack) return;
+                       BindGridView ();
+               }
+
+               protected void OnGridViewInit (object sender, EventArgs e)
+               {
+                       CustomColumn column = new CustomColumn (); 
+                       column.DataField = BoundField.ThisExpression;
+                       gridView.Columns.Add (column);
+               }
+
+               protected void OnGridViewRowEditing (object sender, GridViewEditEventArgs e)
+               {
+                       gridView.EditIndex = e.NewEditIndex;
+                       BindGridView ();
+               }
+
+               protected void OnGridViewEditCancelling (object sender, EventArgs e)
+               {
+                       gridView.EditIndex = -1;
+                       BindGridView ();
+               }
+
+               private void BindGridView ()
+               {
+                       gridView.DataSource = new bool [2];
+                       gridView.DataBind ();
+               }
+       }
+}
\ No newline at end of file