Click here to Skip to main content
Click here to Skip to main content

Dynamic Properties for PropertyGrid

By , 3 Nov 2011
 

Introduction

In this article, I will discuss and show how to get dynamic behavior out of the PropertyGrid control. I would emphasize the word "dynamic" here, and also "dynamic" here means the ability to do things at run-time. Some of the stuff here can also be done using code if you have enough knowledge of the extensibility mechanism of .NET. Dynamic or not, this solution will make your life simpler when it comes to controlling the PropertyGrid control.

This article assumes you have some knowledge of the following:

Don't be nervous if you are not familiar with the above classes, simply read the first two articles in the reference section. That will bring you up-to-speed. All-in-all, this solution encapsulates usage of these classes, so you will work with more plain field by using this solution. Using this solution, you can achieve the following functionalities at run-time:

  • Create properties at run-time and add it to your objects.
  • Get property change notifications to your code for properties created at run-time.
  • Show/hide any property.
  • Enable/disable any property.
  • Show/hide any member of an enumerated data type, including .NET's built-in enumerations.
  • Enable/disable any member of an enumerated data type, including .NET's built-in enumerations.
  • Add custom display name to any member of an enumerated data type, including .NET's built-in enumerations.
  • Add custom description to any member of an enumerated data type, including .NET's built-in enumerations.
  • Provide editor for enumeration data types that has System.FlagsAttribute.
  • Sort properties and/or categories in ascending or descending order using their names or by their IDs (discussed later).
  • Localize your property name, category name, property description, enumeration name, and enumeration description (including .NET's built-in enumerations).
  • A property with Boolean type can show Yes/No or any other display string instead of just True/False.
  • A property with Boolean type can be localized.
  • Show/Hide one or more state icons for properties along with tool tips. Icon size must by 8 pixels by 8 pixels. This is useful to visualize the state of the property (i.e., invalid data). You can show multiple state icons simultaneously. Icons are shown on the right of the property name on the same line of the property on the PropertyGrid.
  • Show value icon for a property value.
  • Show Collection Item as child properties. Any property of type of IEnumerable can be expanded as child properties.

All these can be done at runtime (as well as during coding). During my search, I found some articles which I have listed at the end of this article. They have few of these features in limited form. What I tried to do with my solution was to make a generic solution for the developer so she/he can tell the PropertyGrid what to display, when to display, and how to display from within their class.

Using the code

The sample source code provided in this article contains two C#, VS2008 projects:

Many features have been demonstrated on the sample application in the article. To cover them all in writing would be difficult task, rather one can get the idea by looking at the code. But some features may need some explanation. Those features will be discussed here in a questions and answers format.

Q1: How do I sort properties and categories?

Let's consider this simple class.

public class MyClass()
{
  private DynamicCustomTypeDescriptor m_dctd = null;

  public MyClass()
  {
    m_dctd = ProviderInstaller.Install(this);
    m_dctd.PropertySortOrder = CustomSortOrder.AscendingByName;
    m_dctd.CategorySortOrder = CustomSortOrder.DescendingById;
  }

  [Category("CatA")]
  [DisplayName("PropertyA")]
  [Description("Description of PropertyA")]
  [Id(3, 1)]  //here PropA gets an ID 3 and CatA gets in ID 1 as well.
  public int PropA{...}
  
  [Category("CatB")]
  [DisplayName("PropertyB")]  
  [Description("Description of PropertyB")]
  [Id(2, 2)]  // here PropB gets an ID 2 and CatA gets in ID 2 as well.
  public int PropB{...}
  
  [Category("CatC")]
  [DisplayName("PropertyC")]  
  [Description("Description of PropertyC")]
  [Id(1, 3)]  // here PropC gets an ID 1 and CatA gets in ID 3 as well.
  public bool PropC{...}
  
  [Category("CatC")]
  [DisplayName("PropertyD")]  
  [Description("Description of PropertyD")]
  [Id(4, 3)]  //here PropD gets an ID 4 and CatA gets in ID 3 as well.
  public int PropD{...}

}

In the constructor of the class, we are saying that we would like to sort the properties by name in ascending order and sort categories by ID in descending order.

CustomSortOrder is an enumeration:

public enum CustomSortOrder
{
    // no custom sorting
    None,
    // sort asscending using the property name or category name
    AscendingByName,
    // sort asscending using property id or categor id
    AscendingById,
    // sort descending using the property name or category name
    DescendingByName,
    // sort descending using property id or categor id
    DescendingById,
}

Note that a property without the IdAttribute is same as a property with [Id(0,0)], and IDs cannot be negative values. The PropertySort property of PropertyGrid effects the sorting. The sample application allows you combine all sorting features through GUI. You experiment with different combination.

Q2: How do I show property names, property description, and category names from satellite assemblies for localizing purpose?

Here we will consider the same class, MyClass, from above. To make our class, it needs information to be be able to construct ResourceManager. For that we use a class level attribute called - ClassResourceAttribute. This attribute has three properties:

  • BaseName (string) - Used in ResourceManager construction.
  • Assembly (string) - If specified, used in ResourceManager construction, otherwise Type.Assembly is used.
  • KeyPrefix (object) - If specified, all resource keys must be prefixed with this string. This allows to create unique keys.
[ClassResource(BaseName="TypeDescriptorApp.Properties.Resources", 
         KeyPrefix="MyClass_", Assembly="")]
public class MyClass()
{
....
}

Note that all keys are case-sensitive.

Let's consider the property PropA from our sample class. For display name, PropertyDescriptorManager will search for a string in the following order:

  • Look for a resource string in the target resource file with key MyClass_PropA_Name. The format is: <KeyPrefix>_<PropertyName>_Name.
  • Use the DisplayNameAttribute if it exists. In our case, it will be "PropertyA".
  • Use the property name itself. In our case, it is "PropA".

For the description string of the property PropA, PropertyDescriptorManager will search for a string in the following order:

  • Look for a resource string in the target resource file with key MyClass_PropA_Desc. The format is: <KeyPrefix>_<PropertyName>_Desc.
  • Use the DescriptionAttribute if it exists. In our case, it will be "Description of PropertyA".
  • Otherwise, the description will be blank.

For the category string of property PropA, PropertyDescriptorManager will search for a string in the following order:

  • Look for a resource string in the target resource file with key MyClass_Cat3. The format is: <KeyPrefix>_Cat<CategoryID>.
  • Use the CategoryAttribute if it exists. In our case, it will be "CatA".
  • Otherwise, use the default category, which is "Misc".

Q3: How do I change the property display name, category string, and description string at run-time and also how do I show/hide/enable/disable a property at run-time?

Here we will consider the same class, MyClass, from above. We will modify the constructor to modify some attributes of the property PropA.

public MyClass()
{
    m_dctd = ProviderInstaller.Install(this);
    m_dctd .PropertySortOrder = CustomSortOrder.AscendingByName;
    m_dctd .CategorySortOrder = CustomSortOrder.DescendingByName;
    
    // now lets modify some attribute of PropA
    CustomPropertyDescriptor cpd = m_pdm.GetProperty("PropA");
    cpd.SetDisplayName("New display name of PropA");
    cpd.SetDescription("New description of PropA");
    cpd.SetCategory("New Category of PropA");
    cpd.SetIsReadOnly(true); // disables the property
    cpd.SetIsBrowsable(true);  // hides the property
    cpd.CategoryID = 4;
}

Q4: I have a property of type Int32. This property represents the customer ID. In my database, I have a list of customer names and IDs. I would like for the PropertyGrid to show a drop-down box with customer names and when users pick one from the list, I would like the PropertyGrid to assign the ID to the property instead of the name. How do I do this?

Here we will consider the same class again, MyClass, from above. We will modify the constructor to provide a lookup drop-down box for PropA.

public MyClass()
{
    m_dctd = ProviderInstaller.Install(this);
    m_dctd.PropertySortOrder = CustomSortOrder.AscendingByName;
    m_dctd.CategorySortOrder = CustomSortOrder.DescendingByName;

    CustomPropertyDescriptor cpd = m_pdm.GetProperty("PropA");
    PopululateDropDownListFromDatabaseSource(cpd);
}

private void PopululateDropDownListFromDatabaseSource( CustomPropertyDescriptor cpd )
{      

    cpd.StatandardValues.Clear( );
    string[] arrNames = {"Adam", "Brian", 
        "Russel", "Jones", "Jakob"};
    for (int i = 101; i < 106; i++)
    {
        StandardValueAttribute sva = 
           new StandardValueAttribute(arrNames[i - 101] + 
           " ("+ i.ToString() + ")", i);
        // you can also add an description for any StandardValueAttribute
        sva.Description = "Description of " + sva.DisplayName + ".";
        cpd.StatandardValues.Add(sva);
    }
}

Notice that we have included a description as well. But when you run the code, you will not see the description. Because to show description, you will need a special UITypeEditor. So to make the property PropA to display the description, we will have to add the following attribute to PropA:

[Editor(typeof(StandardValueEditor), typeof(UITypeEditor))]

StandardValueAttribute has these properties:

  • DisplayName (string) - What gets displayed on the screen.
  • Value (object) - The actual value. The actual type of this value must match the type of the property.
  • Description (string) - Description of the value. This requires the StandardValueEditor to have an effect.
  • Visible (bool) - Indicates whether or not to show the value.
  • Enabled (bool) - Indicates whether or not to enable the value. This requires the StandardValueEditor to have an effect.

Q5: In the beginning of this article, you said we can manipulate any member of an enumeration data type, how do I this?

Let's consider this following enumeration type and class:

[EnumResource("TypeDescriptorApp.Properties.Resources")]
[Editor(typeof(StandardValueEditor), typeof(UITypeEditor))]
public enum Position
{
  [StandardValue("First", Description = "Excellen.")]
  One
  [StandardValue("Second", Description = "Good.")]
  Two    

}

[ClassResource("TypeDescriptorApp.Properties.Resources", 
         KeyPrefix="MyEnumClass1_")]
public class MyEnumClass1()
{
  private DynamicCustomTypeDescriptor m_dctd = null;
  public MyEnumClass()
  {
    m_dctd = ProviderInstaller.Install(this);
  }

  public Position PropE{...}
  
  public Position PropF{...}  
}

public class MyEnumClass2()
{
  private DynamicCustomTypeDescriptor m_dctd = null;
  public MyEnumClass()
  {
     m_dctd = ProviderInstaller.Install(this);
  }
  public Position PropG{...}  
}

Note that we are applying StandardValueAttribute on each field of the enumeration. So each field becomes an standard-value, thus you can use the properties of the StandardValueAttribute to show/hide/enable/disable any member of the enumeration. On top of all that, enumeration members can be localized. As always, to localize your class or enum, you have to add the attribute ResourceBaseNameAttribute on the enumeration itself and/or on the class that uses the enumeration. If you apply on both, the class has higher priority than the enumeration. This allows you to override resource information of this enumeration type that is defined in another library that you do not have access to in the source code. You can also override the enumeration resource information at the property level as well which has the highest priority.

Let's create a string table in a resource file that looks like this:

Key Value Comment
Position_One_Name MyString1 enumeration level (priority = 3). Format: <KeyPrefix><Enum FieldName>_Name
Position_One_Desc MyString2 enumeration level (priority = 3). Format: <KeyPrefix><Enum FieldName>_Desc
Position_Two_Name MyString3 enumeration level (priority = 3)
Position_Two_Desc MyString4 enumeration level (priority = 3)
MyEnumClass1_Position_One_Name MyString5 class level override (priority = 2). Format: <KeyPrefix><Enum Name>_<Enum FieldName>_Name
MyEnumClass1_Position_One_Desc MyString6 class level override (priority = 2). Format: <KeyPrefix><Enum Name>_<Enum FieldName>_Desc
MyEnumClass1_Position_Two_Name MyString7 class level override (priority = 2)
MyEnumClass1_Position_Two_Desc MyString8 class level override (priority = 2)
MyEnumClass1_PropE_One_Name MyString9 property level override (priority = 1). Format: <KeyPrefix><Property Name>_<Enum FieldName>_Name
MyEnumClass1_PropE_One_Desc MyString10 property level override (priority = 1). Format: <KeyPrefix><Property Name>_<Enum FieldName>_Desc
MyEnumClass1_PropE_Two_Name MyString11 property level override (priority = 1)
MyEnumClass1_PropE_Two_Desc MyString12 property level override (priority = 1)

Note: 1 is the highest priority and 3 is the lowest priority.

PropE will use the following keys:

  • MyEnumClass1_PropE_One_Name
  • MyEnumClass1_PropE_One_Desc
  • MyEnumClass1_PropE_Two_Name
  • MyEnumClass1_PropE_Two_Desc

Because the enumeration has been overridden at property level.

PropF will use the following keys:

  • MyEnumClass1_Position_One_Name
  • MyEnumClass1_Position_One_Desc
  • MyEnumClass1_Position_Two_Name
  • MyEnumClass1_Position_Two_Desc

Because the enumeration has not been overridden at property for this property, only at class level.

PropG will use the following keys:

  • Position_One_Name
  • Position_One_Desc
  • Position_Two_Name
  • Position_Two_Desc

The enumeration has not been overridden for this class, so it uses what is defined for the enumeration itself.

So as you can see, there is a fallback strategy in place for the enumeration type. That mans you can define all your enumeration in a library, including the resource information, and then another library can use that enumeration as it is or override the resource information as necessary. Just know how to override the keys in the resource.

Q6: I have a Boolean property in my class, I would like to show Yes\No on the PropertyGrid instead of True\False. How do I do this?

Here we will consider the same class, MyClass, from above. PropC is a Boolean type property, so we can do this in the constructor:

public MyClass()
{
  m_dctd = ProviderInstaller.Install(this);
  m_dctd.PropertySortOrder = CustomSortOrder.AscendingByName;
  m_dctd.CategorySortOrder = CustomSortOrder.DescendingByName;
 
  // now lets display Yes/No instead of True/False
  CustomPropertyDescriptor cpd = m_pdm.GetProperty("PropC");
  
  foreach (StandardValueAttribute sva in cpd.StatandardValues)
  {
    if (sva.Value == true) // means it is True part
    {
      sva.DisplayName = "Yes";
    }
    else
    {
      sva.DisplayName = "No";
    }
  }
}

Q7: Can a Boolean property be localized? If so, how?

Yes, a Boolean property can be localized. So you can show "True"/"False" in different languages.

Think of Boolean properties as enumeration properties, like this:

public enum Boolean
{
  True = true;
  False = false;    
}

Note: This above enumeration does not exist in this solution or in .NET.

-- End of Questions and Answers Format--

So, now to localize this, you will have to override the enumeration at class level or property level, or both. Please see Q5 for details.

I hope by now you know how to use this solution. There are other features that are demonstrated in the sample application. If you have questions, feel free to post it here. If you like it, don't forget to vote for it generously, this is the only motivation to get it going.

Points of interest

When you get into the System.ComponentModel.TypeDescriptor class, it is interesting to look at the number of classes that play a role in providing a description for a type.

References

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

About the Author

Mizan Rahman
Denmark Denmark
Member
No Biography provided

Sign Up to vote   Poor Excellent
Add a reason or comment to your vote: x
Votes of 3 or less require a comment

Comments and Discussions

 
You must Sign In to use this message board.
Search this forum  
    Spacing  Noise  Layout  Per page   
QuestionAdding Enum On The FlymemberMrGadget19 Nov '12 - 21:18 
Let's say I have a custom class with a datarow property and an enum (ContactTypes), and I pass a datarow (_DR) into my constructor, which in turn generates various properties on the fly from the columns. One of these colums is a SQL Server bigint and has some combination of bitwise values.
 
I tried the following but it doesn't work:
m_dctd.CreateProperty(col.ColumnName, GetType(ContactTypes), _DR.Item(col).ToString, -1, New BrowsableAttribute(True), New DisplayNameAttribute(col.ColumnName), New DescriptionAttribute("Description of " & col.ColumnName))
 
I have this (clipped for brevity) for the Enum:
	<EnumResource("DynamicTypeDescriptorApp.Properties.Resources")> _
	<Editor(GetType(StandardValueEditor), GetType(UITypeEditor))> _
	<Flags()> _
	Enum ContactTypes As UInt64
		<StandardValue("Not Specified", "Description for None")> _
		None = 0
		<StandardValue("Inactive", "Description for Inactive")> _
		Inactive = 1
		<StandardValue("Contact", "Description for Contact")> _
		Contact = 2
		<StandardValue("Billing", "Description for Billing")> _
		 Billing = 4
		...
	End Enum
 
After the constructor is called from the main thread, the class object is set into a PropertyGrid.SelectedObject. For this property, it shows just the numeric value instead of the "friendly" values. I can open the dropdown and change the selections.
 
If I click outside the dropdown instead of pressing Enter, it throws and exception.
 
If I don't use .ToString with the value argument in CreateProperty(), it throws a conversion exception.
 
Suggestions?
AnswerRe: Adding Enum On The FlymemberMizan Rahman19 Nov '12 - 23:30 
UInt64 for is not a valid type for enum. See http://msdn.microsoft.com/en-us/library/sbbt4032(v=vs.100).aspx[^].
 
Instead of using "enum", you can simply use the values as standard values and add them at run-time for the property.
 
I would recommend you to use my new solution: Dynamic Type Description Framework for PropertyGrid[^]
GeneralRe: Adding Enum On The FlymemberMrGadget20 Nov '12 - 5:21 
It actually translates to ULong, which is valid.
 
I got it working under this older system with:
m_dctd.CreateProperty(col.ColumnName, GetType(ContactTypes), DirectCast([Enum].ToObject(GetType(ContactTypes), _DR.Item(col)), ContactTypes), -1, New BrowsableAttribute(True), New DisplayNameAttribute(col.ColumnName), New DescriptionAttribute("Description of " & col.ColumnName))
 
But it fails with your newer solution when I try this:
pd = New Dyn.PropertyDescriptor(Me.GetType, col.ColumnName, GetType(ContactTypes), DirectCast([Enum].ToObject(GetType(ContactTypes), _DR.Item(col)), ContactTypes))
 
Any ideas?
GeneralMy vote of 5memberMember 18436 Sep '12 - 11:48 
Works great
GeneralMy vote of 5memberMember 18436 Sep '12 - 5:16 
Easy to follow and work frst try
SuggestionDelayed the property value displaymembergloutonsoft7 Feb '12 - 21:11 
Hi !
 
First, I'm very impressed of your work and I thank you for posting it Thumbs Up | :thumbsup:
 
As you seem to be very familiar with the PropertyGrid control, I have a big challenge for you Smile | :) I start working with this control about two years ago and I'm still facing to the same problem without any solution.
 
I have a very large model of which object properties are edited in a property grid with many TypeConverter and UIEditor of my own conception. All works great except that my model is very complex and so, in some case, my default values are long to calculate (a few seconds). My problem is that my application freezes during the property grid is populated. It's clearly not a good user experience...
 
I'm looking for a way to delay the calculation of these default values. For example, display "Loading..." in place of the value while it is calculated. I've tried to do this with a wrapper object that implements the customtypedescriptor to return special propertydescriptors that handle this behavior with all the suitable eventhandlers. But no way, it doesn't work because of an internal object used by the property grid : ReflectPropertyDescriptor. This object invokes directly my property instead of calling the GetValue of my custom propertydescriptor.
 
I have no more idea to solve my problem except to recreate a propertygrid from scratch, and I clearly don't want to do this !
 
Hope for a super cool answer Wink | ;)
 
See ya
 
PS : I'm forced to stay in Framework 2.0, I know, I know, not my choice...
Sébastien Q.
French developper in .NET

GeneralRe: Delayed the property value displaymemberMizan Rahman9 Feb '12 - 22:44 
I am providing a solution that uses the tool in this article.
First consider the following class(read the comments in the code):
 
  public class TestClass
  {
    private DynamicCustomTypeDescriptor m_dctd = null;
    public TestClass()
    {
      m_dctd = ProviderInstaller.Install(this);
    }
    private string m_PropA = String.Empty;
    public string PropA
    {
      get
      {
        return m_PropA;
      }
      set
      {
        m_PropA = value;
      }
    }
 
    private double m_PropB = 0; // the acutal value will have 
                                // to be retrived from database which takes 2 seconds
    [DisplayName("Currency exchange rate")]
    [Browsable(false)]   // initially this property is hidden in the PropertyGrid
    public double PropB
    {
      get
      {
        return m_PropB;
      }
      set
      {
        m_PropB = value;
      }
    }
    // PropC is dummy property and initially visible.
    // PropC is a proxy property for PropB
    private string m_PropC = "Loading...";
    [ReadOnly(true)]
    [DefaultValue("Loading...")]
    [DisplayName("Currency exchange rate")] // has the same display name as PropB
    public string PropC
    {
      get
      {
        return m_PropC;
      }
      set
      {
        m_PropC = value;
      }
    }
    public void LoadDefaultValues()
    {
      BackgroundWorker m_bw = null;
      m_bw = new BackgroundWorker( );
      m_bw.RunWorkerCompleted += new RunWorkerCompletedEventHandler(DefaultValueRetrivalCompleted);
      m_bw.DoWork += new DoWorkEventHandler(RetriveDefaultValue);
      m_bw.RunWorkerAsync( );
    }
 
    void RetriveDefaultValue( object sender, DoWorkEventArgs e )
    {
      // here you will retrive the default values for the properties you require.
      Thread.Sleep(2000);  // simulating long time (2 seconds)
      e.Result = 3.9;  // for example      
    }
 
    void DefaultValueRetrivalCompleted( object sender, RunWorkerCompletedEventArgs e )
    {
      if (!e.Cancelled)
      {
        PropB = Convert.ToDouble( e.Result );
        // now hide PropC
        m_dctd.GetProperty("PropC").SetIsBrowsable(false);
        // and show PropB
        m_dctd.GetProperty("PropB").SetIsBrowsable(true);
        TypeDescriptor.Refresh(this);
      }
    }
  }
 
Then use the following code to bind to the PG:
private void button1_Click( object sender, EventArgs e )
    {
      TestClass tc = new TestClass( );
      this.propertyGrid1.SelectedObject = tc;
      tc.LoadDefaultValues( );
    }
 
Let me know if it works for you.
 
/Mizan
AnswerRe: Delayed the property value displaymembergloutonsoft10 Feb '12 - 2:24 
Very cool solution ! I didn't think that your complete solution is about the dynamic purpose... In fact, it was easy Wink | ;)
 
Now, I have to adapt your solution to my needs. Thank you very much for your great answer !
 
Greetings
QuestionObject properties (deeper level of localization)memberjpmoraes2 Jan '12 - 7:09 
Hi! Very, very good job! Thanks a lot.
I was just wondering about properties that are themselves objects (like Font). In that case, I couldn't be able to put your code to work on it (and I'm thiking the only way to accomplish that is to write a FontConverter class to handle all the "second-level stuff" (deal with "Size", "Bold",... values)). Is this correct or is there something I'm missing?
Thanks!
AnswerRe: Object properties (deeper level of localization)memberMizan Rahman26 Jan '12 - 4:58 
Hi, sorry for delayed reply.
 
You could do something like this:
 
[ClassResource(BaseName="TypeDescriptorApp.Properties.Resources", KeyPrefix="MyPrefix_", Assembly="")]
public class ClassA
{
  private DynamicCustomTypeDescriptor m_dctd = null;
  private DynamicCustomTypeDescriptor m_dctdFont = null;
 

  private Font m_Font = new Font();
  
  public ClassA()
  {
    m_dctd = ProviderInstaller.Install(this);
 
    m_dctdFont = InstallDynamicTypeDescriptorForMyFont();  // install dynamic TD for font
  }
 
  public Font Font
  {
    get
    {
      return m_Font;
    }
    set
    {
      m_Font = value;
      if (m_Font != null)
      {
        m_dctdFont = InstallDynamicTypeDescriptorForMyFont();
      }
    }
  }
 
  private DynamicCustomTypeDescriptor InstallDynamicTypeDescriptorForMyFont()
  {
    return ProviderInstaller.Install(m_Font);
  }
 
}

GeneralRe: Object properties (deeper level of localization)memberjpmoraes26 Jan '12 - 17:09 
Hi Mizan,
Thank you very much! I'll try it, but I think in advance it will work perfectly. I think you did a very good job with these classes.
 
Best regards,
 
Jairo
QuestionConverting the project to .NET Framework 4memberoriginalbudul31 Oct '11 - 7:10 
Hej,
 
I got a second question. I converted the project to .NET Framework 4.
 
If I start the DynamicTypeDescriptorApp then I get an error for PropL. The problem occurs in the following part of DynamicTypeDescriptor.StandardValuesConverter.ConvertTo:
 
TypeConverter tc = TypeDescriptor.GetConverter(propType);
if (tc != null)
{
  object convertedValue = null;
  try
  {
    convertedValue = tc.ConvertTo(context, culture, value, destinationType);
  }
  catch (Exception ex)
  {
    Console.WriteLine(ex.Message);
  }
  if (tc.IsValid(convertedValue))
  {
    return convertedValue;
  }
}
 
In your project (.NET Framework 3.5) the value of tc.IsValid(convertedValue) is true. In .NET Framework 4 the value of tc.IsValid(convertedValue) is false.
 
Do you have an idea about this behaviour? By the way, the same problem also exists with PropK.
AnswerRe: Converting the project to .NET Framework 4memberoriginalbudul1 Nov '11 - 2:36 
originalbudul wrote:
In your project (.NET Framework 3.5) the value of tc.IsValid(convertedValue) is true. In .NET Framework 4 the value of tc.IsValid(convertedValue) is false.

It seems that this behaviour is a result of a change of the IsValid method in .NET Framework 4. This change is described on the MSDN site of the IsValid method.
 
But I am not able to reach the legacy behaviour of the methode. If I adapting the configuration file, then remains the same behavior.
GeneralRe: Converting the project to .NET Framework 4memberMizan Rahman2 Nov '11 - 0:47 
I haven't had time to look into this, and I can't promise you anything when I will have time to invastigate this issue. But if it works with the configuration settings, you can simply go ahead use that.
QuestionCheckbox instead of Yes / No comboboxmemberoriginalbudul26 Oct '11 - 23:43 
Hej,
 
you made a great library which is really usefull!
 
I tried to integrate a checkbox row instead of the localized Yes / No combobox, but it didn't work. The checkbox is always integrated in the combobox.
 
Do you have an idea what do I wrong?
 
Regards
AnswerRe: Checkbox instead of Yes / No comboboxmemberMizan Rahman28 Oct '11 - 8:10 
PropertyGrid does not provide any machanisam for placing CheckBox or any control on the edit portion of a property.
 
One solution can be to create a custom class derriving from PropertyGrid class and under take many painting and aligning code.
 
This article does not provide any such solution as it is designed to work as general solution that will work with any propertygrid, even the propertygrid in the Visual Studio property tool window.
GeneralRe: Checkbox instead of Yes / No comboboxmemberoriginalbudul29 Oct '11 - 3:45 
I've already thought almost. Nevertheless, many thanks for the tip, and especially for the project!
GeneralSecurity level to edit a propertymemberMember 404642930 May '11 - 23:57 
Hi,
 
Before : thanks for your article
 
I provide you a new functionnality
I have worked on the property grid and I wanted that properties with a high security level can be only edited by an administrator (for exemple)
 
So I had created a SecurityLevel attribute with an enum value( AdministratorLevel, MaintenanceLevel, UserLevel...) and disable the property in the property grid if the authetication level was not enough high to edit it.
 
See for more details this post
GeneralNice work!!membertransparency25 May '11 - 22:32 
But...this seems only working for .Net 3.0+
Any suggestion about supporting for .Net 2.0?
Thanks in advance :Smile | :)
GeneralMy vote of 5membergclpixel23 May '11 - 7:42 
thank you,
the property with state image is exactly that what I need. Big Grin | :-D
GeneralAdd new Propertymemberdjdjoko22 May '11 - 12:36 
The tool looks great! How would you add a property dynamically. I could not see from the examples if it is possible.
 
Cheers
GeneralRe: Add new PropertymemberMizan Rahman22 May '11 - 21:53 
please see the CreateOnTheFlyPropertyE() method in DynamicTypeDescriptorApp.TestClass class.
GeneralRe: Add new Propertymemberdjdjoko23 May '11 - 5:09 
works like charm!
GeneralRe: Add new Propertymemberdjdjoko23 May '11 - 6:35 
I tried adding a custom structure dynamically:
 
    public struct MyStruct
    {
        private int _min;
        private int _max;
        private int _step;
 
        public int Min { get { return _min; } set { _min = value; } }
        public int Max { get { return _max; } set { _max = value; } }
        public int Step { get { return _step; } set { _step = value; } }
    }
 
and call it with:
MyStruct ms = new MyStruct();
ms.Max = 1; ms.Min = 2; ms.Step = 1;
dctd.CreateProperty("PropE", typeof(MyStruct), ms,
                                      -1, // insert at the end of the list
                                      new BrowsableAttribute(true),
                                      new DefaultValueAttribute(ms),
                                      new DisplayNameAttribute("PropertyE"),
                                      new DescriptionAttribute("Description of PropertyE"),
                                      new IdAttribute(5, 2));

I get it displayed in the property but can not access the values. I would want it displayed in a similar way like when you add a Form to a propertygrid and see the 'Point', 'Size' or 'Padding' structs being displayed. Is this possible?
Thanks
GeneralRe: Add new Propertymemberdjdjoko23 May '11 - 6:48 
I forgot to add the TypeConverter. Now it works fine!
 
Good Introduction article for accomplishing this[^]

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

Permalink | Advertise | Privacy | Mobile
Web01 | 2.6.130523.1 | Last Updated 3 Nov 2011
Article Copyright 2011 by Mizan Rahman
Everything else Copyright © CodeProject, 1999-2013
Terms of Use
Layout: fixed | fluid