Skip to content

Commit

Permalink
[WinForms] Matching Mono PropertyGrid behaviour with .Net one (#11618)
Browse files Browse the repository at this point in the history
  • Loading branch information
nvoronchev authored and luhenry committed Nov 16, 2018
1 parent e743a7f commit 1076d74
Show file tree
Hide file tree
Showing 3 changed files with 192 additions and 19 deletions.
38 changes: 19 additions & 19 deletions mcs/class/System.Windows.Forms/System.Windows.Forms/GridEntry.cs
Original file line number Diff line number Diff line change
Expand Up @@ -82,8 +82,8 @@ public GridEntry (PropertyGrid propertyGrid, PropertyDescriptor[] properties,
public override bool Expandable {
get {
TypeConverter converter = GetConverter ();
if (converter == null || !converter.GetPropertiesSupported ((ITypeDescriptorContext)this))
return false;
if (converter != null)
return converter.GetPropertiesSupported ((ITypeDescriptorContext)this);

if (GetChildGridItemsCached ().Count > 0)
return true;
Expand Down Expand Up @@ -249,12 +249,11 @@ public override bool Select ()
}

#region ITypeDescriptorContext
void ITypeDescriptorContext.OnComponentChanged ()
{

void ITypeDescriptorContext.OnComponentChanged () {
}

bool ITypeDescriptorContext.OnComponentChanging ()
{
bool ITypeDescriptorContext.OnComponentChanging () {
return false;
}

Expand All @@ -271,20 +270,13 @@ IContainer ITypeDescriptorContext.Container {
}

object ITypeDescriptorContext.Instance {
get {
if (ParentEntry != null && ParentEntry.PropertyOwner != null)
return ParentEntry.PropertyOwner;
return PropertyOwner;
}
get { return PropertyOwner; }
}

PropertyDescriptor ITypeDescriptorContext.PropertyDescriptor {
get {
if (ParentEntry != null && ParentEntry.PropertyDescriptor != null)
return ParentEntry.PropertyDescriptor;
return PropertyDescriptor;
}
get { return PropertyDescriptor; }
}

#endregion

#region IServiceProvider Members
Expand Down Expand Up @@ -792,7 +784,7 @@ private bool IsPropertyMergeable (PropertyDescriptor property)
{
if (property == null)
return false;

MergablePropertyAttribute attrib = property.Attributes [typeof (MergablePropertyAttribute)] as MergablePropertyAttribute;
if (attrib != null && !attrib.AllowMerge)
return false;
Expand Down Expand Up @@ -827,7 +819,7 @@ private string[] GetMergedPropertyNames (object [] objects)
string[] propertyNames = new string [intersection.Count];
for (int i=0; i < intersection.Count; i++)
propertyNames[i] = ((PropertyDescriptor)intersection[i]).Name;

return propertyNames;
}

Expand All @@ -849,8 +841,16 @@ private PropertyDescriptorCollection GetProperties (object propertyOwner, Attrib

Attribute[] atts = new Attribute[attributes.Count];
attributes.CopyTo (atts, 0);

TypeConverter converter = GetConverter ();
if (converter != null)
{
PropertyDescriptorCollection properties = converter.GetProperties ((ITypeDescriptorContext)this, propertyOwner, atts);
return properties ?? new PropertyDescriptorCollection (null);
}

return property_grid.SelectedTab.GetProperties ((ITypeDescriptorContext)this, propertyOwner, atts);
}
#endregion
#endregion // Population
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -128,6 +128,7 @@ System.Windows.Forms/PrintDialogTest.cs
System.Windows.Forms/PrintPreviewControlTest.cs
System.Windows.Forms/ProgressBarTest.cs
System.Windows.Forms/PropertyGridTest.cs
System.Windows.Forms/PropertyGrid_GridEntryTest.cs
System.Windows.Forms/PropertyManagerTest.cs
System.Windows.Forms/RadioButtonTest.cs
System.Windows.Forms/RowStyleTest.cs
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,172 @@
//
// PropertyGrid_GridEntryTest.cs: Test cases for GridEntry placed in PropertyGrid.
//
// Author:
// Nikita Voronchev (nikita.voronchev@ru.axxonsoft.com)
//
// (C) 2018 AxxonSoft (http://www.axxonsoft.com)
//

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Globalization;
using System.Windows.Forms;
using CategoryAttribute = NUnit.Framework.CategoryAttribute;

using NUnit.Framework;

namespace MonoTests.System.Windows.Forms
{
[TestFixture]
public class PropertyGrid_GridEntryTest : TestHelper
{
public void CheckGridItem(INestedObj ownerObject, string propertyName, GridItem gridItem)
{
var context = gridItem as ITypeDescriptorContext;
Assert.NotNull (gridItem, "gridItem is null (propertyName={0})", propertyName);
Assert.NotNull (context, "gridItem is not ITypeDescriptorContext (propertyName={0})", propertyName);

Assert.AreEqual (gridItem.Label, propertyName);

Assert.AreSame (context.Instance, ownerObject);
Assert.AreEqual (context.PropertyDescriptor.PropertyType, ownerObject.PropertyAsINestedObj.GetType());
Assert.AreEqual (context.PropertyDescriptor.Name, propertyName);
}

[Test]
public void ITypeDescriptorContextTest()
{
PropertyGrid pg = new PropertyGrid ();

var rootObj = new NestedObj0 ();
rootObj.Property1 = new NestedObj1 ();
rootObj.Property1.Property2 = new NestedObj2 ();
rootObj.Property1.Property2.Property3 = new NestedObj3 ();
pg.SelectedObject = rootObj;

GridItem gridItem_Property1 = pg.GetRootItem ();
INestedObj ownerOf_Property1 = rootObj;
CheckGridItem(ownerOf_Property1, "Property1", gridItem_Property1);

GridItem gridItem_Property2 = gridItem_Property1.GridItems["Property2"];
INestedObj ownerOf_Property2 = rootObj.Property1;
CheckGridItem(ownerOf_Property2, "Property2", gridItem_Property2);

GridItem gridItem_Property3 = gridItem_Property2.GridItems["Property3"];
INestedObj ownerOf_Property3 = rootObj.Property1.Property2;
CheckGridItem(ownerOf_Property3, "Property3", gridItem_Property3);
}

[Test]
public void CustomExpandableConverterTest()
{
PropertyGrid pg = new PropertyGrid ();

var rootObj = new ConverterTestRootObject ();
pg.SelectedObject = rootObj;

GridItem customExpandableGridItem = pg.GetRootItem ();
Assert.AreEqual ("CustomExpandableProperty", customExpandableGridItem.Label);

var substitutedGridItems = customExpandableGridItem.GridItems;
Assert.AreEqual (1, substitutedGridItems.Count);
Assert.NotNull (substitutedGridItems["SomeProperty"]);
}
}

public static class PropertyGridExtentions
{
// Returns non-Category root `GridItem`.
public static GridItem GetRootItem (this PropertyGrid pg)
{
GridItem gridItem = pg.SelectedGridItem;
Assert.NotNull(gridItem, "No one GridItem is Selected in the PropertyGrid");

while (gridItem.Parent != null && gridItem.Parent.GridItemType == GridItemType.Property)
{
gridItem = gridItem.Parent;
}

return gridItem;
}
}

#region Test Environment: ITypeDescriptorContextTest

[TypeConverter (typeof (ExpandableObjectConverter))]
public interface INestedObj
{
INestedObj PropertyAsINestedObj { get; }
}

// Root object.
class NestedObj0 : INestedObj
{
public NestedObj1 Property1 { get; set; }

[Browsable (false)]
public INestedObj PropertyAsINestedObj { get { return Property1; } }
}

class NestedObj1 : INestedObj
{
public NestedObj2 Property2 { get; set; }

[Browsable (false)]
public INestedObj PropertyAsINestedObj { get { return Property2; } }
}

class NestedObj2 : INestedObj
{
public NestedObj3 Property3 { get; set; }

[Browsable (false)]
public INestedObj PropertyAsINestedObj { get { return Property3; } }
}

class NestedObj3 : INestedObj
{
[Browsable (false)]
public INestedObj PropertyAsINestedObj { get { return null; } }
}

#endregion // Test Environment: ITypeDescriptorContextTest

#region Test Environment: CustomExpandableConverter

[TypeConverter (typeof (ExpandableObjectConverter))]
public class ConverterTestRootObject
{
public ConverterTestPropertiesHolder propertiesHolder = new ConverterTestPropertiesHolder();

[TypeConverter (typeof (CustomExpandableConverter))]
public string CustomExpandableProperty { get; set; }

public ConverterTestRootObject()
{
CustomExpandableProperty = String.Empty;
}
}

public class ConverterTestPropertiesHolder
{
public string SomeProperty { get; set; }
}

public class CustomExpandableConverter : TypeConverter
{
public override bool GetPropertiesSupported (ITypeDescriptorContext context)
{
return true;
}

public override PropertyDescriptorCollection GetProperties (ITypeDescriptorContext context, object value, Attribute[] attributes)
{
ConverterTestRootObject testObject = context.Instance as ConverterTestRootObject;
return TypeDescriptor.GetProperties (testObject.propertiesHolder);
}
}

#endregion // Test Environment: CustomExpandableConverter
}

0 comments on commit 1076d74

Please sign in to comment.