📜 ⬆️ ⬇️

PropertyGrid in Visual Studio: mapping fields associated with collections of objects

PropertyGrid allows you to display a variety of class structures in an easy-to-edit form, and for this it is enough to associate an object of your class with it. However, not all constructions can be immediately displayed without writing additional code. In this article I want to talk about my experience of using PropertyGrid in context:
1. Display a drop-down list of entries, which is a collection of objects.

image

2. Display of the field associated with the collection of objects calling the collection editor.
')
image

As an example, I took the task to implement the management of information about the employee, which implements the class Employee. The class contains two properties. The first is the JobTitle property type (employee position for the drop-down list), the second is the JobTitleCollection property type (collection of employee positions for the collection editor). The task is to display the object of the Employee class in the PropertyGrid as shown in the two figures at the beginning of the article, namely: 1. Display a field in which the user can select one of the employee positions using the drop-down list as in the ComboBox.2 element. Display the field that will allow you to call the editor of the associated collection of posts, and after completing the modification of the collection, display the posts in the PropertyGrid as a list.
Consider more.

Employee class
  1. /// <summary> /// /// </summary> [DisplayName( "" ), Description( " " ), Category( "" )] public class Employee { private JobTitle jt = new JobTitle (); /// <summary> /// , /// ( JobTitle) /// </summary> [DisplayName( "" ), Description( " " ), Category( " " )] [TypeConverter( typeof ( JobTitleTypeConverter ))] public JobTitle jobtitle { get { return jt; } set { jt = value ; } } private JobTitleCollection jobTitles = new JobTitleCollection (); /// <summary> /// , /// PropertyGrid /// </summary> [Description( " " ), Category( "" ), DisplayName( "" )] [TypeConverter( typeof ( JobTitleCollectionConverter ))] public JobTitleCollection JobTitles { get { return jobTitles; } set { jobTitles = value ; } } }
  2. /// <summary> /// /// </summary> [DisplayName( "" ), Description( " " ), Category( "" )] public class Employee { private JobTitle jt = new JobTitle (); /// <summary> /// , /// ( JobTitle) /// </summary> [DisplayName( "" ), Description( " " ), Category( " " )] [TypeConverter( typeof ( JobTitleTypeConverter ))] public JobTitle jobtitle { get { return jt; } set { jt = value ; } } private JobTitleCollection jobTitles = new JobTitleCollection (); /// <summary> /// , /// PropertyGrid /// </summary> [Description( " " ), Category( "" ), DisplayName( "" )] [TypeConverter( typeof ( JobTitleCollectionConverter ))] public JobTitleCollection JobTitles { get { return jobTitles; } set { jobTitles = value ; } } }
  3. /// <summary> /// /// </summary> [DisplayName( "" ), Description( " " ), Category( "" )] public class Employee { private JobTitle jt = new JobTitle (); /// <summary> /// , /// ( JobTitle) /// </summary> [DisplayName( "" ), Description( " " ), Category( " " )] [TypeConverter( typeof ( JobTitleTypeConverter ))] public JobTitle jobtitle { get { return jt; } set { jt = value ; } } private JobTitleCollection jobTitles = new JobTitleCollection (); /// <summary> /// , /// PropertyGrid /// </summary> [Description( " " ), Category( "" ), DisplayName( "" )] [TypeConverter( typeof ( JobTitleCollectionConverter ))] public JobTitleCollection JobTitles { get { return jobTitles; } set { jobTitles = value ; } } }
  4. /// <summary> /// /// </summary> [DisplayName( "" ), Description( " " ), Category( "" )] public class Employee { private JobTitle jt = new JobTitle (); /// <summary> /// , /// ( JobTitle) /// </summary> [DisplayName( "" ), Description( " " ), Category( " " )] [TypeConverter( typeof ( JobTitleTypeConverter ))] public JobTitle jobtitle { get { return jt; } set { jt = value ; } } private JobTitleCollection jobTitles = new JobTitleCollection (); /// <summary> /// , /// PropertyGrid /// </summary> [Description( " " ), Category( "" ), DisplayName( "" )] [TypeConverter( typeof ( JobTitleCollectionConverter ))] public JobTitleCollection JobTitles { get { return jobTitles; } set { jobTitles = value ; } } }
  5. /// <summary> /// /// </summary> [DisplayName( "" ), Description( " " ), Category( "" )] public class Employee { private JobTitle jt = new JobTitle (); /// <summary> /// , /// ( JobTitle) /// </summary> [DisplayName( "" ), Description( " " ), Category( " " )] [TypeConverter( typeof ( JobTitleTypeConverter ))] public JobTitle jobtitle { get { return jt; } set { jt = value ; } } private JobTitleCollection jobTitles = new JobTitleCollection (); /// <summary> /// , /// PropertyGrid /// </summary> [Description( " " ), Category( "" ), DisplayName( "" )] [TypeConverter( typeof ( JobTitleCollectionConverter ))] public JobTitleCollection JobTitles { get { return jobTitles; } set { jobTitles = value ; } } }
  6. /// <summary> /// /// </summary> [DisplayName( "" ), Description( " " ), Category( "" )] public class Employee { private JobTitle jt = new JobTitle (); /// <summary> /// , /// ( JobTitle) /// </summary> [DisplayName( "" ), Description( " " ), Category( " " )] [TypeConverter( typeof ( JobTitleTypeConverter ))] public JobTitle jobtitle { get { return jt; } set { jt = value ; } } private JobTitleCollection jobTitles = new JobTitleCollection (); /// <summary> /// , /// PropertyGrid /// </summary> [Description( " " ), Category( "" ), DisplayName( "" )] [TypeConverter( typeof ( JobTitleCollectionConverter ))] public JobTitleCollection JobTitles { get { return jobTitles; } set { jobTitles = value ; } } }
  7. /// <summary> /// /// </summary> [DisplayName( "" ), Description( " " ), Category( "" )] public class Employee { private JobTitle jt = new JobTitle (); /// <summary> /// , /// ( JobTitle) /// </summary> [DisplayName( "" ), Description( " " ), Category( " " )] [TypeConverter( typeof ( JobTitleTypeConverter ))] public JobTitle jobtitle { get { return jt; } set { jt = value ; } } private JobTitleCollection jobTitles = new JobTitleCollection (); /// <summary> /// , /// PropertyGrid /// </summary> [Description( " " ), Category( "" ), DisplayName( "" )] [TypeConverter( typeof ( JobTitleCollectionConverter ))] public JobTitleCollection JobTitles { get { return jobTitles; } set { jobTitles = value ; } } }
  8. /// <summary> /// /// </summary> [DisplayName( "" ), Description( " " ), Category( "" )] public class Employee { private JobTitle jt = new JobTitle (); /// <summary> /// , /// ( JobTitle) /// </summary> [DisplayName( "" ), Description( " " ), Category( " " )] [TypeConverter( typeof ( JobTitleTypeConverter ))] public JobTitle jobtitle { get { return jt; } set { jt = value ; } } private JobTitleCollection jobTitles = new JobTitleCollection (); /// <summary> /// , /// PropertyGrid /// </summary> [Description( " " ), Category( "" ), DisplayName( "" )] [TypeConverter( typeof ( JobTitleCollectionConverter ))] public JobTitleCollection JobTitles { get { return jobTitles; } set { jobTitles = value ; } } }
  9. /// <summary> /// /// </summary> [DisplayName( "" ), Description( " " ), Category( "" )] public class Employee { private JobTitle jt = new JobTitle (); /// <summary> /// , /// ( JobTitle) /// </summary> [DisplayName( "" ), Description( " " ), Category( " " )] [TypeConverter( typeof ( JobTitleTypeConverter ))] public JobTitle jobtitle { get { return jt; } set { jt = value ; } } private JobTitleCollection jobTitles = new JobTitleCollection (); /// <summary> /// , /// PropertyGrid /// </summary> [Description( " " ), Category( "" ), DisplayName( "" )] [TypeConverter( typeof ( JobTitleCollectionConverter ))] public JobTitleCollection JobTitles { get { return jobTitles; } set { jobTitles = value ; } } }
  10. /// <summary> /// /// </summary> [DisplayName( "" ), Description( " " ), Category( "" )] public class Employee { private JobTitle jt = new JobTitle (); /// <summary> /// , /// ( JobTitle) /// </summary> [DisplayName( "" ), Description( " " ), Category( " " )] [TypeConverter( typeof ( JobTitleTypeConverter ))] public JobTitle jobtitle { get { return jt; } set { jt = value ; } } private JobTitleCollection jobTitles = new JobTitleCollection (); /// <summary> /// , /// PropertyGrid /// </summary> [Description( " " ), Category( "" ), DisplayName( "" )] [TypeConverter( typeof ( JobTitleCollectionConverter ))] public JobTitleCollection JobTitles { get { return jobTitles; } set { jobTitles = value ; } } }
  11. /// <summary> /// /// </summary> [DisplayName( "" ), Description( " " ), Category( "" )] public class Employee { private JobTitle jt = new JobTitle (); /// <summary> /// , /// ( JobTitle) /// </summary> [DisplayName( "" ), Description( " " ), Category( " " )] [TypeConverter( typeof ( JobTitleTypeConverter ))] public JobTitle jobtitle { get { return jt; } set { jt = value ; } } private JobTitleCollection jobTitles = new JobTitleCollection (); /// <summary> /// , /// PropertyGrid /// </summary> [Description( " " ), Category( "" ), DisplayName( "" )] [TypeConverter( typeof ( JobTitleCollectionConverter ))] public JobTitleCollection JobTitles { get { return jobTitles; } set { jobTitles = value ; } } }
  12. /// <summary> /// /// </summary> [DisplayName( "" ), Description( " " ), Category( "" )] public class Employee { private JobTitle jt = new JobTitle (); /// <summary> /// , /// ( JobTitle) /// </summary> [DisplayName( "" ), Description( " " ), Category( " " )] [TypeConverter( typeof ( JobTitleTypeConverter ))] public JobTitle jobtitle { get { return jt; } set { jt = value ; } } private JobTitleCollection jobTitles = new JobTitleCollection (); /// <summary> /// , /// PropertyGrid /// </summary> [Description( " " ), Category( "" ), DisplayName( "" )] [TypeConverter( typeof ( JobTitleCollectionConverter ))] public JobTitleCollection JobTitles { get { return jobTitles; } set { jobTitles = value ; } } }
  13. /// <summary> /// /// </summary> [DisplayName( "" ), Description( " " ), Category( "" )] public class Employee { private JobTitle jt = new JobTitle (); /// <summary> /// , /// ( JobTitle) /// </summary> [DisplayName( "" ), Description( " " ), Category( " " )] [TypeConverter( typeof ( JobTitleTypeConverter ))] public JobTitle jobtitle { get { return jt; } set { jt = value ; } } private JobTitleCollection jobTitles = new JobTitleCollection (); /// <summary> /// , /// PropertyGrid /// </summary> [Description( " " ), Category( "" ), DisplayName( "" )] [TypeConverter( typeof ( JobTitleCollectionConverter ))] public JobTitleCollection JobTitles { get { return jobTitles; } set { jobTitles = value ; } } }
  14. /// <summary> /// /// </summary> [DisplayName( "" ), Description( " " ), Category( "" )] public class Employee { private JobTitle jt = new JobTitle (); /// <summary> /// , /// ( JobTitle) /// </summary> [DisplayName( "" ), Description( " " ), Category( " " )] [TypeConverter( typeof ( JobTitleTypeConverter ))] public JobTitle jobtitle { get { return jt; } set { jt = value ; } } private JobTitleCollection jobTitles = new JobTitleCollection (); /// <summary> /// , /// PropertyGrid /// </summary> [Description( " " ), Category( "" ), DisplayName( "" )] [TypeConverter( typeof ( JobTitleCollectionConverter ))] public JobTitleCollection JobTitles { get { return jobTitles; } set { jobTitles = value ; } } }
  15. /// <summary> /// /// </summary> [DisplayName( "" ), Description( " " ), Category( "" )] public class Employee { private JobTitle jt = new JobTitle (); /// <summary> /// , /// ( JobTitle) /// </summary> [DisplayName( "" ), Description( " " ), Category( " " )] [TypeConverter( typeof ( JobTitleTypeConverter ))] public JobTitle jobtitle { get { return jt; } set { jt = value ; } } private JobTitleCollection jobTitles = new JobTitleCollection (); /// <summary> /// , /// PropertyGrid /// </summary> [Description( " " ), Category( "" ), DisplayName( "" )] [TypeConverter( typeof ( JobTitleCollectionConverter ))] public JobTitleCollection JobTitles { get { return jobTitles; } set { jobTitles = value ; } } }
  16. /// <summary> /// /// </summary> [DisplayName( "" ), Description( " " ), Category( "" )] public class Employee { private JobTitle jt = new JobTitle (); /// <summary> /// , /// ( JobTitle) /// </summary> [DisplayName( "" ), Description( " " ), Category( " " )] [TypeConverter( typeof ( JobTitleTypeConverter ))] public JobTitle jobtitle { get { return jt; } set { jt = value ; } } private JobTitleCollection jobTitles = new JobTitleCollection (); /// <summary> /// , /// PropertyGrid /// </summary> [Description( " " ), Category( "" ), DisplayName( "" )] [TypeConverter( typeof ( JobTitleCollectionConverter ))] public JobTitleCollection JobTitles { get { return jobTitles; } set { jobTitles = value ; } } }
  17. /// <summary> /// /// </summary> [DisplayName( "" ), Description( " " ), Category( "" )] public class Employee { private JobTitle jt = new JobTitle (); /// <summary> /// , /// ( JobTitle) /// </summary> [DisplayName( "" ), Description( " " ), Category( " " )] [TypeConverter( typeof ( JobTitleTypeConverter ))] public JobTitle jobtitle { get { return jt; } set { jt = value ; } } private JobTitleCollection jobTitles = new JobTitleCollection (); /// <summary> /// , /// PropertyGrid /// </summary> [Description( " " ), Category( "" ), DisplayName( "" )] [TypeConverter( typeof ( JobTitleCollectionConverter ))] public JobTitleCollection JobTitles { get { return jobTitles; } set { jobTitles = value ; } } }
  18. /// <summary> /// /// </summary> [DisplayName( "" ), Description( " " ), Category( "" )] public class Employee { private JobTitle jt = new JobTitle (); /// <summary> /// , /// ( JobTitle) /// </summary> [DisplayName( "" ), Description( " " ), Category( " " )] [TypeConverter( typeof ( JobTitleTypeConverter ))] public JobTitle jobtitle { get { return jt; } set { jt = value ; } } private JobTitleCollection jobTitles = new JobTitleCollection (); /// <summary> /// , /// PropertyGrid /// </summary> [Description( " " ), Category( "" ), DisplayName( "" )] [TypeConverter( typeof ( JobTitleCollectionConverter ))] public JobTitleCollection JobTitles { get { return jobTitles; } set { jobTitles = value ; } } }
  19. /// <summary> /// /// </summary> [DisplayName( "" ), Description( " " ), Category( "" )] public class Employee { private JobTitle jt = new JobTitle (); /// <summary> /// , /// ( JobTitle) /// </summary> [DisplayName( "" ), Description( " " ), Category( " " )] [TypeConverter( typeof ( JobTitleTypeConverter ))] public JobTitle jobtitle { get { return jt; } set { jt = value ; } } private JobTitleCollection jobTitles = new JobTitleCollection (); /// <summary> /// , /// PropertyGrid /// </summary> [Description( " " ), Category( "" ), DisplayName( "" )] [TypeConverter( typeof ( JobTitleCollectionConverter ))] public JobTitleCollection JobTitles { get { return jobTitles; } set { jobTitles = value ; } } }
  20. /// <summary> /// /// </summary> [DisplayName( "" ), Description( " " ), Category( "" )] public class Employee { private JobTitle jt = new JobTitle (); /// <summary> /// , /// ( JobTitle) /// </summary> [DisplayName( "" ), Description( " " ), Category( " " )] [TypeConverter( typeof ( JobTitleTypeConverter ))] public JobTitle jobtitle { get { return jt; } set { jt = value ; } } private JobTitleCollection jobTitles = new JobTitleCollection (); /// <summary> /// , /// PropertyGrid /// </summary> [Description( " " ), Category( "" ), DisplayName( "" )] [TypeConverter( typeof ( JobTitleCollectionConverter ))] public JobTitleCollection JobTitles { get { return jobTitles; } set { jobTitles = value ; } } }
  21. /// <summary> /// /// </summary> [DisplayName( "" ), Description( " " ), Category( "" )] public class Employee { private JobTitle jt = new JobTitle (); /// <summary> /// , /// ( JobTitle) /// </summary> [DisplayName( "" ), Description( " " ), Category( " " )] [TypeConverter( typeof ( JobTitleTypeConverter ))] public JobTitle jobtitle { get { return jt; } set { jt = value ; } } private JobTitleCollection jobTitles = new JobTitleCollection (); /// <summary> /// , /// PropertyGrid /// </summary> [Description( " " ), Category( "" ), DisplayName( "" )] [TypeConverter( typeof ( JobTitleCollectionConverter ))] public JobTitleCollection JobTitles { get { return jobTitles; } set { jobTitles = value ; } } }
  22. /// <summary> /// /// </summary> [DisplayName( "" ), Description( " " ), Category( "" )] public class Employee { private JobTitle jt = new JobTitle (); /// <summary> /// , /// ( JobTitle) /// </summary> [DisplayName( "" ), Description( " " ), Category( " " )] [TypeConverter( typeof ( JobTitleTypeConverter ))] public JobTitle jobtitle { get { return jt; } set { jt = value ; } } private JobTitleCollection jobTitles = new JobTitleCollection (); /// <summary> /// , /// PropertyGrid /// </summary> [Description( " " ), Category( "" ), DisplayName( "" )] [TypeConverter( typeof ( JobTitleCollectionConverter ))] public JobTitleCollection JobTitles { get { return jobTitles; } set { jobTitles = value ; } } }
  23. /// <summary> /// /// </summary> [DisplayName( "" ), Description( " " ), Category( "" )] public class Employee { private JobTitle jt = new JobTitle (); /// <summary> /// , /// ( JobTitle) /// </summary> [DisplayName( "" ), Description( " " ), Category( " " )] [TypeConverter( typeof ( JobTitleTypeConverter ))] public JobTitle jobtitle { get { return jt; } set { jt = value ; } } private JobTitleCollection jobTitles = new JobTitleCollection (); /// <summary> /// , /// PropertyGrid /// </summary> [Description( " " ), Category( "" ), DisplayName( "" )] [TypeConverter( typeof ( JobTitleCollectionConverter ))] public JobTitleCollection JobTitles { get { return jobTitles; } set { jobTitles = value ; } } }
  24. /// <summary> /// /// </summary> [DisplayName( "" ), Description( " " ), Category( "" )] public class Employee { private JobTitle jt = new JobTitle (); /// <summary> /// , /// ( JobTitle) /// </summary> [DisplayName( "" ), Description( " " ), Category( " " )] [TypeConverter( typeof ( JobTitleTypeConverter ))] public JobTitle jobtitle { get { return jt; } set { jt = value ; } } private JobTitleCollection jobTitles = new JobTitleCollection (); /// <summary> /// , /// PropertyGrid /// </summary> [Description( " " ), Category( "" ), DisplayName( "" )] [TypeConverter( typeof ( JobTitleCollectionConverter ))] public JobTitleCollection JobTitles { get { return jobTitles; } set { jobTitles = value ; } } }
  25. /// <summary> /// /// </summary> [DisplayName( "" ), Description( " " ), Category( "" )] public class Employee { private JobTitle jt = new JobTitle (); /// <summary> /// , /// ( JobTitle) /// </summary> [DisplayName( "" ), Description( " " ), Category( " " )] [TypeConverter( typeof ( JobTitleTypeConverter ))] public JobTitle jobtitle { get { return jt; } set { jt = value ; } } private JobTitleCollection jobTitles = new JobTitleCollection (); /// <summary> /// , /// PropertyGrid /// </summary> [Description( " " ), Category( "" ), DisplayName( "" )] [TypeConverter( typeof ( JobTitleCollectionConverter ))] public JobTitleCollection JobTitles { get { return jobTitles; } set { jobTitles = value ; } } }
  26. /// <summary> /// /// </summary> [DisplayName( "" ), Description( " " ), Category( "" )] public class Employee { private JobTitle jt = new JobTitle (); /// <summary> /// , /// ( JobTitle) /// </summary> [DisplayName( "" ), Description( " " ), Category( " " )] [TypeConverter( typeof ( JobTitleTypeConverter ))] public JobTitle jobtitle { get { return jt; } set { jt = value ; } } private JobTitleCollection jobTitles = new JobTitleCollection (); /// <summary> /// , /// PropertyGrid /// </summary> [Description( " " ), Category( "" ), DisplayName( "" )] [TypeConverter( typeof ( JobTitleCollectionConverter ))] public JobTitleCollection JobTitles { get { return jobTitles; } set { jobTitles = value ; } } }
  27. /// <summary> /// /// </summary> [DisplayName( "" ), Description( " " ), Category( "" )] public class Employee { private JobTitle jt = new JobTitle (); /// <summary> /// , /// ( JobTitle) /// </summary> [DisplayName( "" ), Description( " " ), Category( " " )] [TypeConverter( typeof ( JobTitleTypeConverter ))] public JobTitle jobtitle { get { return jt; } set { jt = value ; } } private JobTitleCollection jobTitles = new JobTitleCollection (); /// <summary> /// , /// PropertyGrid /// </summary> [Description( " " ), Category( "" ), DisplayName( "" )] [TypeConverter( typeof ( JobTitleCollectionConverter ))] public JobTitleCollection JobTitles { get { return jobTitles; } set { jobTitles = value ; } } }
  28. /// <summary> /// /// </summary> [DisplayName( "" ), Description( " " ), Category( "" )] public class Employee { private JobTitle jt = new JobTitle (); /// <summary> /// , /// ( JobTitle) /// </summary> [DisplayName( "" ), Description( " " ), Category( " " )] [TypeConverter( typeof ( JobTitleTypeConverter ))] public JobTitle jobtitle { get { return jt; } set { jt = value ; } } private JobTitleCollection jobTitles = new JobTitleCollection (); /// <summary> /// , /// PropertyGrid /// </summary> [Description( " " ), Category( "" ), DisplayName( "" )] [TypeConverter( typeof ( JobTitleCollectionConverter ))] public JobTitleCollection JobTitles { get { return jobTitles; } set { jobTitles = value ; } } }
  29. /// <summary> /// /// </summary> [DisplayName( "" ), Description( " " ), Category( "" )] public class Employee { private JobTitle jt = new JobTitle (); /// <summary> /// , /// ( JobTitle) /// </summary> [DisplayName( "" ), Description( " " ), Category( " " )] [TypeConverter( typeof ( JobTitleTypeConverter ))] public JobTitle jobtitle { get { return jt; } set { jt = value ; } } private JobTitleCollection jobTitles = new JobTitleCollection (); /// <summary> /// , /// PropertyGrid /// </summary> [Description( " " ), Category( "" ), DisplayName( "" )] [TypeConverter( typeof ( JobTitleCollectionConverter ))] public JobTitleCollection JobTitles { get { return jobTitles; } set { jobTitles = value ; } } }
  30. /// <summary> /// /// </summary> [DisplayName( "" ), Description( " " ), Category( "" )] public class Employee { private JobTitle jt = new JobTitle (); /// <summary> /// , /// ( JobTitle) /// </summary> [DisplayName( "" ), Description( " " ), Category( " " )] [TypeConverter( typeof ( JobTitleTypeConverter ))] public JobTitle jobtitle { get { return jt; } set { jt = value ; } } private JobTitleCollection jobTitles = new JobTitleCollection (); /// <summary> /// , /// PropertyGrid /// </summary> [Description( " " ), Category( "" ), DisplayName( "" )] [TypeConverter( typeof ( JobTitleCollectionConverter ))] public JobTitleCollection JobTitles { get { return jobTitles; } set { jobTitles = value ; } } }
  31. /// <summary> /// /// </summary> [DisplayName( "" ), Description( " " ), Category( "" )] public class Employee { private JobTitle jt = new JobTitle (); /// <summary> /// , /// ( JobTitle) /// </summary> [DisplayName( "" ), Description( " " ), Category( " " )] [TypeConverter( typeof ( JobTitleTypeConverter ))] public JobTitle jobtitle { get { return jt; } set { jt = value ; } } private JobTitleCollection jobTitles = new JobTitleCollection (); /// <summary> /// , /// PropertyGrid /// </summary> [Description( " " ), Category( "" ), DisplayName( "" )] [TypeConverter( typeof ( JobTitleCollectionConverter ))] public JobTitleCollection JobTitles { get { return jobTitles; } set { jobTitles = value ; } } }
JobTitle grade
  1. /// <summary>
  2. /// Employee's position
  3. /// </ summary>
  4. [DisplayName ( "Position" ), Description ( "Position of Employee" ), Category ( "Information about Employee" )]
  5. [TypeConverter ( typeof ( JobTitleConverter ))]
  6. public class JobTitle : MyItem
  7. {
  8. /// <summary>
  9. /// Constructor
  10. /// </ summary>
  11. public JobTitle () {}
  12. /// <summary>
  13. /// Constructor
  14. /// </ summary>
  15. /// <param name = "ID"> Record ID </ param>
  16. /// <param name = "ItemName"> Name </ param>
  17. public JobTitle ( int ID, string ItemName)
  18. {
  19. this .ID = ID;
  20. this .ItemName = ItemName;
  21. }
  22. }
The solution of the problem
You need to implement a class to convert the JobTitle type to a form so that the PropertyGrid object can correctly display the drop-down list of posts. It is assumed that at the moment of creating the Employee class object several posts will be added to the collection to be displayed in the list, after which the collection can be displayed in a drop-down list with further editing through the Employee class object's First field. - JobTitleTypeConverter. Further, in addition to this class, additional classes will be implemented necessary for solving the problem.
The source code of the example is available to you. Link duplicated at the end of the article.
At once I want to note that the information management of the object displayed in the PropertyGrid is carried out using attributes. This allows you to set the desired display style. Further attributes will be actively used in the implementation of the solution.
  1. /// <summary>
  2. /// JobTitle type conversion class
  3. /// Converts to the String type and back to JobTitle
  4. /// Also, allows you to display a collection of posts in the form of a drop-down list.
  5. /// </ summary>
  6. public class JobTitleTypeConverter : ExpandableObjectConverter
  7. {
  8. /// <summary>
  9. /// Returns a value indicating whether the object supports a standard set of values.
  10. /// which can be selected from the list.
  11. /// If you do not force the value to true, then
  12. /// that the handler will not accept your method GetStandardValues ​​and you will not see
  13. /// your list of values ​​to select
  14. /// </ summary>
  15. /// <param name = "context"> </ param>
  16. /// <returns> </ returns>
  17. public override bool GetStandardValuesSupported ( ITypeDescriptorContext context)
  18. {
  19. return true ;
  20. }
  21. /// <summary>
  22. /// This method can be excluded, but in the future it will allow using this class of converter.
  23. /// to call from different classes.
  24. /// To do this, it is enough to add to the case section the name of another class that should contain a property
  25. /// JobTitle with the link function with a drop-down list
  26. /// </ summary>
  27. /// <param name = "context"> </ param>
  28. /// <returns> </ returns>
  29. private JobTitleCollection GetCollection (System.ComponentModel. ITypeDescriptorContext context)
  30. {
  31. JobTitleCollection collection = new JobTitleCollection ();
  32. switch (context.Instance.GetType (). Name)
  33. {
  34. case "Employee" :
  35. collection = ((Employee) context.Instance) .JobTitles;
  36. break ;
  37. default :
  38. collection = ((Employee) context.Instance) .JobTitles;
  39. break ;
  40. }
  41. return collection;
  42. }
  43. /// <summary>
  44. /// The method returns a list of values ​​from the collection of posts for display in the drop-down
  45. /// list of values ​​PropertyGrid for employee position
  46. /// </ summary>
  47. /// <param name = "context"> </ param>
  48. /// <returns> </ returns>
  49. public override TypeConverter. StandardValuesCollection GetStandardValues ​​( ITypeDescriptorContext context)
  50. {
  51. return new StandardValuesCollection (GetCollection (context));
  52. }
  53. /// <summary>
  54. /// The method checks if the received property value can be converted from the user.
  55. /// in the type we need
  56. /// </ summary>
  57. /// <param name = "context"> </ param>
  58. /// <param name = "destinationType"> </ param>
  59. /// <returns> </ returns>
  60. public override bool CanConvertTo ( ITypeDescriptorContext context, Type destinationType)
  61. {
  62. if (destinationType.Equals ( typeof ( string )))
  63. {
  64. return true ;
  65. }
  66. else
  67. {
  68. return false ;
  69. }
  70. }
  71. /// <summary>
  72. /// Conversion of JobTitle type to a string to display the value in the PropertyGrid field
  73. /// </ summary>
  74. /// <param name = "context"> </ param>
  75. /// <param name = "culture"> </ param>
  76. /// <param name = "value"> </ param>
  77. /// <param name = "destinationType"> </ param>
  78. /// <returns> </ returns>
  79. public override object ConvertTo ( ITypeDescriptorContext context,
  80. System.Globalization. CultureInfo culture, object value , Type destinationType)
  81. {
  82. if (destinationType == typeof ( string ) && value is JobTitle )
  83. {
  84. JobTitle item = ( JobTitle ) value ;
  85. Return item.FullName;
  86. }
  87. return base .ConvertTo (context, culture, value , destinationType);
  88. }
  89. /// <summary>
  90. /// Check for the possibility of reverse conversion of the string representation to the type JobTitle
  91. /// </ summary>
  92. /// <param name = "context"> </ param>
  93. /// <param name = "sourceType"> </ param>
  94. /// <returns> </ returns>
  95. public override bool CanConvertFrom ( ITypeDescriptorContext context, Type sourceType)
  96. {
  97. if (sourceType.Equals ( typeof ( string )))
  98. {
  99. return true ;
  100. }
  101. else
  102. {
  103. return false ;
  104. }
  105. }
  106. /// <summary>
  107. /// Convert a string representation of a post to a JobTitle type.
  108. /// The disadvantage of this conversion is that the correctness of the cast operation depends on the format.
  109. /// string representation of the JobTitle type, namely, from duplicate values.
  110. /// </ summary>
  111. /// <param name = "context"> </ param>
  112. /// <param name = "culture"> </ param>
  113. /// <param name = "value"> </ param>
  114. /// <returns> </ returns>
  115. public override object ConvertFrom ( ITypeDescriptorContext context,
  116. System.Globalization. CultureInfo culture, object value )
  117. {
  118. if ( value .GetType () == typeof ( string ))
  119. {
  120. JobTitle itemSelected = GetCollection (context) .Count.Equals ( 0 )?
  121. new JobTitle (): GetCollection (context) [ 0 ];
  122. foreach ( JobTitle Item in GetCollection (context))
  123. {
  124. string sCraftName = Item.FullName;
  125. if (sCraftName.Equals (( string ) value ))
  126. {
  127. itemSelected = Item;
  128. }
  129. }
  130. return itemSelected;
  131. }
  132. else
  133. return base .ConvertFrom (context, culture, value );
  134. }
  135. /// <summary>
  136. /// Returns a value indicating whether the collection of standard values ​​is an exhaustive list.
  137. /// returned by the method.
  138. ///
  139. /// false - data can be entered manually
  140. /// true - just select from the list
  141. /// </ summary>
  142. /// <param name = "context"> </ param>
  143. /// <returns> </ returns>
  144. public override bool GetStandardValuesExclusive ( ITypeDescriptorContext context)
  145. {
  146. return true ;
  147. }
  148. /// <summary>
  149. /// Method Constructor
  150. /// </ summary>
  151. public JobTitleTypeConverter () {}
  152. }
Post collection class
To implement the post collection class, you need to inherit it from the CollectionBase class and implement the ICustomTypeDescriptor interface. This will allow the collection to be used to display correctly in the PropertyGrid. This is done using the implementation of the JobTitleCollectionPropertyDescriptor class property descriptor class.
  1. /// <summary>
  2. /// Class collection of posts
  3. /// Contains methods that provide information for describing the contents of collection properties
  4. /// and display in the PropertyGrid
  5. /// </ summary>
  6. [DisplayName ( "List of Positions" ), Description ( "List of Employee Positions" ), Category ( "Employee Information" )]
  7. public class JobTitleCollection : CollectionBase , ICustomTypeDescriptor
  8. {
  9. #region Collection Methods
  10. public void Add ( JobTitle Item)
  11. {
  12. this .List.Add (Item);
  13. }
  14. public void Remove ( JobTitle Item)
  15. {
  16. this .List.Remove (Item);
  17. }
  18. public JobTitle this [ int Index]
  19. {
  20. get { return ( JobTitle ) this .List [Index]; }
  21. }
  22. #endregion
  23. #region Implementing the ICustomTypeDescriptor Interface
  24. public String GetClassName ()
  25. {
  26. return TypeDescriptor.GetClassName ( this , true );
  27. }
  28. public AttributeCollection GetAttributes ()
  29. {
  30. return TypeDescriptor.GetAttributes ( this , true );
  31. }
  32. public String GetComponentName ()
  33. {
  34. return TypeDescriptor.GetComponentName ( this , true );
  35. }
  36. public TypeConverter GetConverter ()
  37. {
  38. Return TypeDescriptor.GetConverter ( this , true );
  39. }
  40. public EventDescriptor GetDefaultEvent ()
  41. {
  42. return TypeDescriptor.GetDefaultEvent ( this , true );
  43. }
  44. public PropertyDescriptor GetDefaultProperty ()
  45. {
  46. return TypeDescriptor.GetDefaultProperty ( this , true );
  47. }
  48. public object GetEditor ( Type editorBaseType)
  49. {
  50. return TypeDescriptor.GetEditor ( this , editorBaseType, true );
  51. }
  52. public EventDescriptorCollection GetEvents ( Attribute [] attributes)
  53. {
  54. return TypeDescriptor.GetEvents ( this , attributes, true );
  55. }
  56. public EventDescriptorCollection GetEvents ()
  57. {
  58. return TypeDescriptor.GetEvents ( this , true );
  59. }
  60. public object GetPropertyOwner ( PropertyDescriptor pd)
  61. {
  62. return this ;
  63. }
  64. public PropertyDescriptorCollection GetProperties ( Attribute [] attributes)
  65. {
  66. return GetProperties ();
  67. }
  68. public PropertyDescriptorCollection GetProperties ()
  69. {
  70. PropertyDescriptorCollection pds = new PropertyDescriptorCollection ( null );
  71. for ( int i = 0 ; i < this .List.Count; i ++)
  72. {
  73. JobTitleCollectionPropertyDescriptor pd = new JobTitleCollectionPropertyDescriptor ( this , i);
  74. pds.Add (pd);
  75. }
  76. return pds;
  77. }
  78. #endregion
  79. }
Additional class for describing properties of a collection of JobTitle objects
  1. /// <summary>
  2. /// Property description class for a collection of JobTitle objects
  3. /// </ summary>
  4. public class JobTitleCollectionPropertyDescriptor : PropertyDescriptor
  5. {
  6. private JobTitleCollection collection = null ;
  7. private int index = - 1 ;
  8. public JobTitleCollectionPropertyDescriptor (JobTitleCollection coll, int idx):
  9. base ( "#" + idx.ToString (), null )
  10. {
  11. this .collection = coll;
  12. this .index = idx;
  13. }
  14. public override AttributeCollection Attributes
  15. {
  16. get
  17. {
  18. return new AttributeCollection ( null );
  19. }
  20. }
  21. public override bool CanResetValue ( object component)
  22. {
  23. return true ;
  24. }
  25. public override Type ComponentType
  26. {
  27. get
  28. {
  29. return this .collection.GetType ();
  30. }
  31. }
  32. public override string DisplayName
  33. {
  34. get
  35. {
  36. JobTitle Item = this .collection [index];
  37. Return Item.FullName;
  38. }
  39. }
  40. public override string Description
  41. {
  42. get
  43. {
  44. JobTitle Item = this .collection [index];
  45. StringBuilder sb = new StringBuilder ();
  46. sb.Append (Item.ItemName);
  47. sb.Append ( "," );
  48. sb.Append (index + 1 );
  49. return sb.ToString ();
  50. }
  51. }
  52. public override object GetValue ( object component)
  53. {
  54. return this .collection [index];
  55. }
  56. public override bool IsReadOnly
  57. {
  58. get { return false ; }
  59. }
  60. public override string Name
  61. {
  62. get { return "#" + index.ToString (); }
  63. }
  64. public override Type PropertyType
  65. {
  66. get { return this .collection [index] .GetType (); }
  67. }
  68. public override void ResetValue ( object component)
  69. {
  70. }
  71. public override bool ShouldSerializeValue ( object component)
  72. {
  73. return true ;
  74. }
  75. public override void SetValue ( object component, object value )
  76. {
  77. }
  78. }
Additional class of posts collection converter
  1. /// <summary>
  2. /// Converter class for the standard collection display in a PropertyGrid
  3. /// Replaces the designation "(Collection)" with "(Posts ...)"
  4. /// </ summary>
  5. public class JobTitleCollectionConverter : ExpandableObjectConverter
  6. {
  7. public override object ConvertTo ( ITypeDescriptorContext context, System.Globalization. CultureInfo culture,
  8. object value , Type destType)
  9. {
  10. if (destType == typeof ( string ) && value is JobTitleCollection)
  11. {
  12. return "(Posts ...)" ;
  13. }
  14. return base .ConvertTo (context, culture, value , destType);
  15. }
  16. }
Additional class of post type converter
  1. /// <summary>
  2. /// Class performing the JobTitle type conversion for correct display in the collection editor
  3. /// If you do not implement it, the internal name will be displayed in the JobTitle collection editor window
  4. /// JobTitle class
  5. /// </ summary>
  6. public class JobTitleConverter : ExpandableObjectConverter
  7. {
  8. public override object ConvertTo ( ITypeDescriptorContext context, System.Globalization. CultureInfo culture,
  9. object value , Type destType)
  10. {
  11. if (destType == typeof ( string ) && value is JobTitle)
  12. {
  13. JobTitle jobtitle = (JobTitle) value ;
  14. return jobtitle.FullName;
  15. }
  16. return base .ConvertTo (context, culture, value , destType);
  17. }
  18. }
Class ancestor employee classes and positions
  1. /// <summary>
  2. /// Ancestor class of entities
  3. /// </ summary>
  4. public class MyItem
  5. {
  6. private int iID = - 1 ;
  7. /// <summary>
  8. /// record ID
  9. /// </ summary>
  10. [Description ( "Item Number" ), Category ( "Collections" ), DisplayName ( "Number" )]
  11. public int ID
  12. {
  13. get { return iID; }
  14. set {iID = value ; }
  15. }
  16. private string sItemName = "" ;
  17. /// <summary>
  18. /// Name
  19. /// </ summary>
  20. [Description ( "Item Name" ), Category ( "Collections" ), DisplayName ( "Title" )]
  21. public string ItemName
  22. {
  23. get { return sItemName; }
  24. set {sItemName = value ; }
  25. }
  26. /// <summary>
  27. /// Full name of the object
  28. /// </ summary>
  29. [Browsable ( false )]
  30. public string FullName
  31. {
  32. get
  33. {
  34. return String .Format ( "{0} No. {1}" , ItemName, ID.ToString ());
  35. }
  36. }
  37. }
You can download the source code of the example .
The article was created based on the PropertyGrid FAQ and is intended to complement it.

Source: https://habr.com/ru/post/78024/


All Articles