Custom sort collection in PropertyGrid

Grids for WPF Forum

Posted 4 months ago by Miguel A.
Version: 18.1.0674
Avatar

Hi,

I have a class like this:

class Foo
{
[Category("Foo")]
public int X;
//...
[Category("Test", TypeConverter(typeof(MyCollectionConverter))]
public Dictionary<int,string> MyDic = new Dictionary<int,string>()
}

  and a typeconverter which shows the integer key as hex decimal string:

sealed class MyCollectionConverter : ExpandableObjectConverter {


		public override PropertyDescriptorCollection GetProperties(ITypeDescriptorContext context, object value, Attribute[] attributes) {
			var properties = new ArrayList();
			var dictionary = (Dictionary<int, int>)value;
			foreach (var e in dictionary) {
				properties.Add(new DictionaryPropertyDescriptor(dictionary, e.Key));
			}

			var props = (PropertyDescriptor[])properties.ToArray(typeof(PropertyDescriptor));

			return new PropertyDescriptorCollection(props);
		}

		class DictionaryPropertyDescriptor : PropertyDescriptor {
			readonly IDictionary _dictionary;
			public readonly int _key;

			internal DictionaryPropertyDescriptor(IDictionary d, int key)
				: base(key.ToString(), null) {
				_dictionary = d;
				_key = key;
			}		

			public override Type PropertyType => _dictionary[_key].GetType();

			public override void SetValue(object component, object value) {

			}
			public override string Description => _key.ToString("X");

			public override object GetValue(object component) {
				return ((int)_dictionary[_key]).ToString("X");
			}

			public override bool IsReadOnly => true;

			public override Type ComponentType => null;

			public override bool CanResetValue(object component) => false;

			public override void ResetValue(object component) {
			}

			public override bool ShouldSerializeValue(object component) => false;
		}
	}

My problem is that in propertygrid the dictionary is alphabetically sorted because the description is a hex decimal string which results in (0x)100 is before (0x)8. But I would like to sort it by integer or by the order in dictionary so (0x)8 is before (0x)100 as 8 (int) is smaller than 64 (int).

But I also don't want to change the overall order of the propertygrid, only the dictionary values need to be sorted. Is there a way to achieve this?

//edit: I've seen the Sort category in the demo application but is there a way to do this via converter / reflection attribute instead?

[Modified 4 months ago]

Comments (3)

Answer - Posted 4 months ago by Actipro Software Support - Cleveland, OH, USA
Avatar

Hi Miguel,

The virtual DataFactoryBase.SortDataModels method is where all sorting occurs.  By default it will use the DataModelSortComparer defined in the PropertyGrid.SortComparer property.

I'm not sure there would be a good way to do this special sorting in an inherited DataModelSortComparer since that only passes in the two IDataModels to compare.

Therefore you'd probably have to override that SortDataModels method in a custom data factory class and look at the request.Parent to see if it's a data model for one of these dictionaries.  If so, then apply your custom sort logic in the list of data models that is returned.  Otherwise, call the base method.  Then set the PropertyGrid.DataFactory property to an instance of your custom data factory class.


Actipro Software Support

Posted 4 months ago by Miguel A.
Avatar

Thanks, that kinda works. But my dictionary is shown like this:

-Test (category)

--MyDic

---Item[0]

But I would prefer it is not showing the dictionary as parent instead it should show the items directly. Is there a way to achieve this? This was also confusing when trying to sort as the sort showing in the demo examples only apply to the children of a category (which is only the dictionary) but not sorting sub items.

Posted 4 months ago by Actipro Software Support - Cleveland, OH, USA
Avatar

Hello,

While the PropertyGrid Custom Data Factory QuickStart shows an example of moving properties around, collections are special-cased a bit so they can be watched/handled properly, and I'm not sure those concepts would work there.  So most likely you would not be able to put the items directly in the category and still have it update properly as the collection changes.

But in our Collection Display Mode QuickStart, I set it to have Expandable collections and then I saw the data factory's SortDataModels method was being called.  So it should be getting called for collection items per that test.


Actipro Software Support

The latest build of this product (v2018.1 build 0675) was released 2 months ago, which was after the last post in this thread.

Add Comment

Please log in to a validated account to post comments.