[.NET 5] PropertyGridでReadOnlyを動的に変更したい

1 min read読了の目安(約1700字

0. 概要

Name Value
Framework .NET 5
Language C#/WinForm

「.NET Framework 4.8」ではReflectionで変更できたが、「.NET 5」では不可能になっていた。

1. コード

PropertyGridがGetPropertiesを取得するタイミングで、Settingクラスが標準で返すPropertyDescriptorCollectionを差し替える。

以下の例では、「Filepath」のReadOnlyAttributetrueに変更している。

[TypeConverter(typeof(CustomTypeConverter))]
public class Setting
{  
  [ReadOnly(false)]
  public string Filepath { get; set; }

  public int Value1 { get; set; }

  [ReadOnly(true)]
  public int Value2 { get; set; }
}

internal class CustomTypeConverter : TypeConverter
{
  public override PropertyDescriptorCollection GetProperties(ITypeDescriptorContext context, object value, Attribute[] attributes)
  {
     var list = new List<PropertyDescriptor>();

     foreach (PropertyDescriptor descriptor in TypeDescriptor.GetProperties(value, attributes))
     {
        if (descriptor.Name == "Filepath")
        {
           var attributes_ = new Attribute[descriptor.Attributes.Count];
           descriptor.Attributes.CopyTo(attributes_, 0);
           var attributeList = new List<Attribute>(attributes_);

           attributeList.Remove(ReadOnlyAttribute.No);
           attributeList.Add(ReadOnlyAttribute.Yes);

           list.Add(TypeDescriptor.CreateProperty(value.GetType(), descriptor, attributeList.ToArray()));
        }
        else
        {
           list.Add(descriptor);
        }
     }

     return new PropertyDescriptorCollection(list.ToArray());
  }

  public override bool GetPropertiesSupported(ITypeDescriptorContext context)
  {
     return true;
  }
}   

2. 備考

■ Source Browser
.NET Core
.NET Framework 4.8