Merge pull request #948 from ermshiperete/bug-xamarin-2394
authorMiguel de Icaza <miguel@gnome.org>
Thu, 15 May 2014 21:22:31 +0000 (17:22 -0400)
committerMiguel de Icaza <miguel@gnome.org>
Thu, 15 May 2014 21:22:31 +0000 (17:22 -0400)
[MWF] Fixes related to Height and MinimumHeight in DataGridView

mcs/class/Managed.Windows.Forms/System.Windows.Forms/DataGridView.cs
mcs/class/Managed.Windows.Forms/System.Windows.Forms/DataGridViewRow.cs
mcs/class/Managed.Windows.Forms/System.Windows.Forms/DataGridViewRowHeightInfoNeededEventArgs.cs
mcs/class/Managed.Windows.Forms/System.Windows.Forms_test.dll.sources
mcs/class/Managed.Windows.Forms/Test/System.Windows.Forms/DataGridViewRowHeightInfoNeededEventArgsTests.cs [new file with mode: 0644]
mcs/class/Managed.Windows.Forms/Test/System.Windows.Forms/DataGridViewRowTest.cs
mcs/class/Managed.Windows.Forms/Test/System.Windows.Forms/DataGridViewTest.cs

index b977be3590508626a06e04e467dadd1cecd19071..393d5cba9aebfd3d0da99fd14f52067b5b2f70e6 100644 (file)
@@ -3140,6 +3140,20 @@ namespace System.Windows.Forms {
                                InvalidateRow (i);
                }
 
+               private void UpdateRowHeightInfo (DataGridViewRow row)
+               {
+                       DataGridViewRowHeightInfoNeededEventArgs rowInfo =
+                               new DataGridViewRowHeightInfoNeededEventArgs (row.Index, row.Height, row.MinimumHeight);
+                       OnRowHeightInfoNeeded (rowInfo);
+
+                       if (row.Height != rowInfo.Height || row.MinimumHeight != rowInfo.MinimumHeight) {
+                               row.MinimumHeight = rowInfo.MinimumHeight;
+                               row.Height = rowInfo.Height;
+                               OnRowHeightInfoPushed (new DataGridViewRowHeightInfoPushedEventArgs (row.Index, rowInfo.Height,
+                                                                                                       rowInfo.MinimumHeight));
+                       }
+               }
+
                public void UpdateRowHeightInfo (int rowIndex, bool updateToEnd)
                {
                        if (rowIndex < 0 && updateToEnd)
@@ -3159,33 +3173,12 @@ namespace System.Windows.Forms {
 
                        if (updateToEnd) {
                                for (int i = rowIndex; i < Rows.Count; i++) {
-                                       DataGridViewRow row = Rows[i];
-                                       if (!row.Visible)
-                                               continue;
-
-                                       DataGridViewRowHeightInfoNeededEventArgs rowInfo = 
-                                               new DataGridViewRowHeightInfoNeededEventArgs (row.Index, row.Height, row.MinimumHeight);
-                                       OnRowHeightInfoNeeded (rowInfo);
-
-                                       if (row.Height != rowInfo.Height || row.MinimumHeight != rowInfo.MinimumHeight) {
-                                               row.Height = rowInfo.Height;
-                                               row.MinimumHeight = rowInfo.MinimumHeight;
-                                               OnRowHeightInfoPushed (new DataGridViewRowHeightInfoPushedEventArgs (row.Index, rowInfo.Height, 
-                                                                                                                    rowInfo.MinimumHeight));
-                                       }
+                                       DataGridViewRow row = Rows [i];
+                                       if (row.Visible)
+                                               UpdateRowHeightInfo (row);
                                }
                        } else {
-                               DataGridViewRow row = Rows[rowIndex];
-                               DataGridViewRowHeightInfoNeededEventArgs rowInfo = 
-                                       new DataGridViewRowHeightInfoNeededEventArgs (row.Index, row.Height, row.MinimumHeight);
-                               OnRowHeightInfoNeeded (rowInfo);
-
-                               if (row.Height != rowInfo.Height || row.MinimumHeight != rowInfo.MinimumHeight) {
-                                       row.Height = rowInfo.Height;
-                                       row.MinimumHeight = rowInfo.MinimumHeight;
-                                       OnRowHeightInfoPushed (new DataGridViewRowHeightInfoPushedEventArgs (row.Index, rowInfo.Height, 
-                                                                                                            rowInfo.MinimumHeight));
-                               }
+                               UpdateRowHeightInfo (Rows [rowIndex]);
                        }
                }
 
index df638ee5dd1a771b1e7ded164d5038ca879a0c42..8130f70df0a6003fc6b5249e996e120d7c90d15f 100644 (file)
@@ -196,9 +196,10 @@ namespace System.Windows.Forms
                                
                                if (height != value) {
                                        if (value < minimumHeight) {
-                                               throw new ArgumentOutOfRangeException("Height can't be less than MinimumHeight.");
+                                               height = minimumHeight;
+                                       } else {
+                                               height = value;
                                        }
-                                       height = value;
                                        if (DataGridView != null) {
                                                DataGridView.Invalidate ();
                                                DataGridView.OnRowHeightChanged(new DataGridViewRowEventArgs(this));
@@ -254,6 +255,10 @@ namespace System.Windows.Forms
                                        if (value < 2 || value > Int32.MaxValue) {
                                                throw new ArgumentOutOfRangeException("MinimumHeight should be between 2 and Int32.MaxValue.");
                                        }
+                                       if (height < value) {
+                                               // don't let height get less than minimumHeight!
+                                               Height = value;
+                                       }
                                        minimumHeight = value;
                                        if (DataGridView != null) {
                                                DataGridView.OnRowMinimumHeightChanged(new DataGridViewRowEventArgs(this));
index 0bd0384e4cda3dcca418ee339a45b63bfa03c1b2..5dc5a9b086a8be9c41c0188fa5a5101699c7b7da 100644 (file)
@@ -39,7 +39,7 @@ namespace System.Windows.Forms {
 
                public int Height {
                        get { return height; }
-                       set { height = value; }
+                       set { height = value < minimumHeight ? minimumHeight : value; }
                }
 
                public int MinimumHeight {
index a18ec387a895587a17b10f5669f3221e6ee1c173..e14341db1a9f62588375b5e9dcbf84466e5f7dca 100644 (file)
@@ -63,6 +63,7 @@ System.Windows.Forms/DataGridViewLinkCellTest.cs
 System.Windows.Forms/DataGridViewImageCellTest.cs
 System.Windows.Forms/DataGridViewRowCollectionTest.cs
 System.Windows.Forms/DataGridViewRowHeaderTest.cs
+System.Windows.Forms/DataGridViewRowHeightInfoNeededEventArgsTests.cs
 System.Windows.Forms/DataGridViewRowTest.cs
 System.Windows.Forms/DataGridViewTest.cs
 System.Windows.Forms/DataGridViewTextBoxCellTest.cs
diff --git a/mcs/class/Managed.Windows.Forms/Test/System.Windows.Forms/DataGridViewRowHeightInfoNeededEventArgsTests.cs b/mcs/class/Managed.Windows.Forms/Test/System.Windows.Forms/DataGridViewRowHeightInfoNeededEventArgsTests.cs
new file mode 100644 (file)
index 0000000..64c2866
--- /dev/null
@@ -0,0 +1,101 @@
+// Copyright (c) 2014 SIL International
+// This software is licensed under the MIT License (http://opensource.org/licenses/MIT)
+using System;
+using System.Windows.Forms;
+using NUnit.Framework;
+using CategoryAttribute = NUnit.Framework.CategoryAttribute;
+
+namespace MonoTests.System.Windows.Forms
+{
+       [TestFixture]
+       public class DataGridViewRowHeightInfoNeededEventArgsTests
+       {
+               struct RowInfo
+               {
+                       public RowInfo (DataGridViewRowHeightInfoNeededEventArgs e)
+                       {
+                               Height = e.Height;
+                               MinimumHeight = e.MinimumHeight;
+                       }
+
+                       public int Height;
+                       public int MinimumHeight;
+               }
+
+               class DummyDataGridView : DataGridView
+               {
+                       public RowInfo RowInfo;
+
+                       protected override void OnRowHeightInfoNeeded (DataGridViewRowHeightInfoNeededEventArgs e)
+                       {
+                               base.OnRowHeightInfoNeeded (e);
+                               RowInfo = new RowInfo (e);
+                       }
+               }
+
+               [Test]
+               [Category("NotWorking")]
+               public void HeightCantBeLessThanCurrentMinimumHeight ()
+               {
+                       using (var dgv = new DummyDataGridView ()) {
+                               // Setup
+                               dgv.VirtualMode = true;
+                               dgv.RowCount = 1;
+                               dgv.Rows [0].MinimumHeight = 5;
+                               dgv.Rows [0].Height = 10;
+                               dgv.RowHeightInfoNeeded += (sender, e) => {
+                                       e.Height = 2;
+                                       e.MinimumHeight = 2;
+                               };
+                               dgv.UpdateRowHeightInfo (0, false);
+
+                               // Execute - this triggers the RowHeightInfoNeeded event
+                               // This test doesn't work because of different implementation details in .NET
+                               // and Mono: on .NET RowHeightInfoNeeded gets called for the first time when
+                               // executing the following line. In Mono RowHeightInfoNeeded got already called
+                               // while executing dgv.UpdateRowHeightInfo. This means that when RowHeightInfoNeeded
+                               // gets called now MinimumHeight is already set to 2, allowing Height to become
+                               // 2 as well.
+                               // On .NET since it is the first time Height will be set to 5 (the current
+                               // MinimumHeight value).
+                               // The .NET behaviour is surprising since the order of setting the information
+                               // in RowHeightInfoNeeded shouldn't matter, therefore I don't think it's worth
+                               // changing the behaviour in Mono. Even more so since there is an easy
+                               // workaround: simply swapping the two lines in the RowHeighInfoNeeded event
+                               // handler works around the problem.
+                               var dummy = dgv.Rows [0].Height;
+
+                               // Verify
+                               var rowHeightInfo = dgv.RowInfo;
+                               Assert.AreEqual (5, rowHeightInfo.Height, "#A1"); // 5 because of buggy .NET behaviour
+                               Assert.AreEqual (2, rowHeightInfo.MinimumHeight, "#A2");
+                       }
+               }
+
+               [Test]
+               public void SettingHeightAfterChangingMinimumHeight ()
+               {
+                       using (var dgv = new DummyDataGridView ()) {
+                               // Setup
+                               dgv.VirtualMode = true;
+                               dgv.RowCount = 1;
+                               dgv.Rows [0].MinimumHeight = 5;
+                               dgv.Rows [0].Height = 10;
+                               dgv.RowHeightInfoNeeded += (sender, e) => {
+                                       e.MinimumHeight = 2;
+                                       e.Height = 2;
+                               };
+                               dgv.UpdateRowHeightInfo (0, false);
+
+                               // Execute - this triggers the RowHeightInfoNeeded event
+                               var dummy = dgv.Rows [0].Height;
+
+                               // Verify
+                               var rowHeightInfo = dgv.RowInfo;
+                               Assert.AreEqual (2, rowHeightInfo.Height, "#B1");
+                               Assert.AreEqual (2, rowHeightInfo.MinimumHeight, "#B2");
+                       }
+               }
+       }
+}
+
index e22e4628fdda56a43aeb4ee388aee5537035a1b7..475aa85a23f33a10cec2cde68ac625095a970274 100644 (file)
@@ -62,26 +62,63 @@ namespace MonoTests.System.Windows.Forms {
                }
 
                [Test]
-               [Category ("NotWorking")]
-               public void MinimumHeight ()
+               public void Height_SetHeightLessThanMinHeightSilentlySetsToMinHeight()
                {
-                       DataGridViewRow row = new DataGridViewRow();
-                       Assert.IsTrue (row.MinimumHeight > 0, "#A1");
-                       Assert.IsFalse (row.Height > row.MinimumHeight, "#A2");
-                       row.MinimumHeight = 40;
-                       row.Height = 50;
-                       Assert.AreEqual (40, row.MinimumHeight, "#B1");
-                       Assert.AreEqual (50, row.Height, "#B2");
-                       row.MinimumHeight = 20;
-                       Assert.AreEqual (20, row.MinimumHeight, "#C1");
-                       Assert.AreEqual (20, row.Height, "#C2");
-                       row.MinimumHeight = 40;
-                       Assert.AreEqual (40, row.MinimumHeight, "#D1");
-                       Assert.AreEqual (40, row.Height, "#D2");
+                       using (var row = new DataGridViewRow ()) {
+                               // Setup
+                               row.MinimumHeight = 5;
+
+                               // Execute
+                               row.Height = 2;
+
+                               // Verify
+                               Assert.AreEqual (5, row.Height, "Height didn't get set to MinimumHeight");
+                       }
+               }
+
+               [Test]
+               public void MinimumHeight_DefaultValues ()
+               {
+                       using (DataGridViewRow row = new DataGridViewRow ()) {
+                               Assert.IsTrue (row.MinimumHeight > 0, "#A1");
+                               Assert.IsTrue (row.Height >= row.MinimumHeight, "#A2");
+                       }
+               }
+
+               [Test]
+               public void MinimumHeight_SetValues ()
+               {
+                       using (DataGridViewRow row = new DataGridViewRow ()) {
+                               row.MinimumHeight = 40;
+                               row.Height = 50;
+                               Assert.AreEqual (40, row.MinimumHeight, "#B1");
+                               Assert.AreEqual (50, row.Height, "#B2");
+                       }
+               }
+
+               [Test]
+               public void MinimumHeight_IncreaseMinHeightChangesHeight ()
+               {
+                       using (DataGridViewRow row = new DataGridViewRow ()) {
+                               row.MinimumHeight = 20;
+                               row.Height = 20;
+                               Assert.AreEqual (20, row.MinimumHeight, "#C1");
+                               Assert.AreEqual (20, row.Height, "#C2");
+                               row.MinimumHeight = 40;
+                               Assert.AreEqual (40, row.MinimumHeight, "#D1");
+                               Assert.AreEqual (40, row.Height, "#D2");
+                       }
+               }
+
+               [Test]
+               [ExpectedException(typeof(ArgumentOutOfRangeException))]
+               public void MinimumHeight_SettingToLessThan2ThrowsException ()
+               {
+                       using (DataGridViewRow row = new DataGridViewRow ()) {
+                               // We expect the next line to throw an ArgumentOutOfRangeException
+                               row.MinimumHeight = 1;
+                       }
                }
-               
-               
-               
 
                [Test]
                [NUnit.Framework.Category ("NotWorking")]       // DGVComboBox not implemented
index 3ff2e076c342bacd3b3228b6ed4417f709d584dc..666bd7a6fecc52a679e6f7c0b43dc86512b32f24 100644 (file)
@@ -2513,6 +2513,62 @@ namespace MonoTests.System.Windows.Forms
                        Assert.IsNull (dgvr2.DataGridView, "#5");
                        Assert.IsNull (dgvr3.DataGridView, "#6");
                }
+
+               [Test] // Xamarin bug #2394
+               public void Bug2394_RowHeightLessThanOldMinHeightVirtMode ()
+               {
+                       using (var dgv = new DataGridView ()) {
+                               dgv.VirtualMode = true;
+                               dgv.RowCount = 1;
+                               dgv.Rows [0].MinimumHeight = 5;
+                               dgv.Rows [0].Height = 10;
+                               dgv.RowHeightInfoNeeded += (sender, e) => {
+                                       // NOTE: the order is important here.
+                                       e.MinimumHeight = 2;
+                                       e.Height = 2;
+                               };
+                               dgv.UpdateRowHeightInfo (0, false);
+                               Assert.AreEqual (2, dgv.Rows [0].Height);
+                               Assert.AreEqual (2, dgv.Rows [0].MinimumHeight);
+                       }
+               }
+
+               [Test] // Xamarin bug #2394
+               public void Bug2394_RowHeightLessThanMinHeightVirtMode ()
+               {
+                       using (var dgv = new DataGridView ()) {
+                               dgv.VirtualMode = true;
+                               dgv.RowCount = 1;
+                               dgv.Rows [0].Height = 10;
+                               dgv.Rows [0].MinimumHeight = 5;
+                               dgv.RowHeightInfoNeeded += (sender, e) => {
+                                       // Setting the height to a value less than the minimum height
+                                       // will be silently ignored and instead set to MinimumHeight.
+                                       e.Height = 2;
+                               };
+                               dgv.UpdateRowHeightInfo (0, false);
+                               Assert.AreEqual(5, dgv.Rows[0].Height);
+                               Assert.AreEqual(5, dgv.Rows[0].MinimumHeight);
+                       }
+               }
+
+               [Test] // Xamarin bug #2394
+               public void Bug2394_MinHeightGreaterThanOldRowHeightVirtMode ()
+               {
+                       using (var dgv = new DataGridView ()) {
+                               dgv.VirtualMode = true;
+                               dgv.RowCount = 1;
+                               dgv.Rows [0].Height = 10;
+                               dgv.Rows [0].MinimumHeight = 5;
+                               dgv.RowHeightInfoNeeded += (sender, e) => {
+                                       e.MinimumHeight = 30;
+                                       e.Height = 40;
+                               };
+                               dgv.UpdateRowHeightInfo (0, false);
+                               Assert.AreEqual (40, dgv.Rows [0].Height);
+                               Assert.AreEqual (30, dgv.Rows [0].MinimumHeight);
+                       }
+               }
        }
        
        [TestFixture]