Question

I have a class with some public fields and I want to show this fields in PropertyGrid on a form:

public class FileInfo
{
     ...

     [DisplayName("Messages")]
     public Collection<MessageInfo> MessageInfos { get; set; }
}

The problem is that I also want to disable Collection for some instances of this class, so user can't even enter its editor. And I need to make it from the code, not from the designer.

Even if I make this field ReadOnly by adding attribute [ReadOnly(true)] it will allow user to enter its editor by pressing (...):

enter image description here

Was it helpful?

Solution

You can do it if you define a custom UITypeEditor that overrides the standard CollectionEditor, something like this:

    public class FileInfo
    {
        [DisplayName("Messages")]
        [Editor(typeof(MyCustomCollectionEditor), typeof(UITypeEditor))]
        public Collection<MessageInfo> MessageInfos { get; set; }
    }

    public class MyCustomCollectionEditor : CollectionEditor // needs a reference to System.Design.dll
    {
        public MyCustomCollectionEditor(Type type)
            : base(type)
        {
        }

        public override UITypeEditorEditStyle GetEditStyle(ITypeDescriptorContext context)
        {
            if (DontShowForSomeReason(context)) // you need to implement this
                return UITypeEditorEditStyle.None; // disallow edit (hide the small browser button)

            return base.GetEditStyle(context);
        }
    }

OTHER TIPS

Depending on the design of your program. You could use inheritance possibly. You don't really supply info in regard to who has access to your object...etc. With the lack of details other then it needs to be in code and not the designer this is a simple solution. Or you may need something more robust.

public class FileInfo
{
     //...
}

public class FileInfoWithCollection : FileInfo {
     [DisplayName("Messages")]
     public Collection<MessageInfo> MessageInfos { 
          get; 
          set;
     }    
}

Another option could be to roll your own Inherited copy of Collection that overrides any method that could modify the collection. Without more info and by the fact that a collection is a ref type I doubt you will get a sure fire answer.

Add a ReadOnly attribute on top of the property.

[DisplayName("Messages")]
[ReadOnly(true)]
public Collection<MessageInfo> MessageInfos { get; set; }

Haven't tested yet, hopefully it works.

Taken from this link.

Add a boolean flag that indicates whether or not the collection is read-only:

public class FileInfo
{
    ...

    [DisplayName("Messages")]
    public Collection<MessageInfo> MessageInfos { get; set; }
    public bool IsReadOnly;
}

Set IsReadOnly to true for those instances that you want to disable. You can then enable/ disable your UI based on the state of the flag.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top