我有一个PropertyGrid,它绑定了一些类属性.

我try 将其ReadOnly属性更改为true,然后在我的编辑器类中更改该值,然后在带有反射的properties setter方法中重置它,但这无法正常工作,因为textfield仍处于焦点模式,我仍然可以进行更改.此外,对我来说,这更像是一种变通方法,而不是一种可接受的解决方案.

有没有办法只通过EditorComponent类而不是PropertyGrid访问我的属性的setter?

我的自定义编辑器类:

public override object EditValue(ITypeDescriptorContext context, IServiceProvider provider, object value)
{
   using (EditorForm f = new Forms.EditorForm(value.ToString()))
   {
      if (f.ShowDialog() == System.Windows.Forms.DialogResult.OK)
      {
         PropertyDescriptor descriptor = context.PropertyDescriptor;
         if (descriptor != null)
         {
            ReadOnlyAttribute attribute = descriptor.Attributes[typeof(ReadOnlyAttribute)] as ReadOnlyAttribute;
            if (attribute != null)
            {
               System.Reflection.FieldInfo fieldToChange = attribute.GetType().GetField("isReadOnly", System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance);
               if (fieldToChange != null)
               {
                  fieldToChange.SetValue(attribute, false); // setting it to false
                  value = f.Text;
               }
            }
         }
      }
   }
   return value;
}

在这之后,我用setter方法重新更改它:

private string _myText = String.Empty;
[Editor(typeof(...), typeof(UITypeEditor)),
ReadOnly(true)]
public string MyText
{
   get { return _myText; }
   set
   {
      _myText = value;
      PropertyDescriptor descriptor = TypeDescriptor.GetProperties(this)["MyText"];
      if (descriptor != null)
      {
         ReadOnlyAttribute attribute = descriptor.Attributes[typeof(ReadOnlyAttribute)] as ReadOnlyAttribute;
         if (attribute != null)
         {
            System.Reflection.FieldInfo fieldToChange = attribute.GetType().GetField("isReadOnly", System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance);
             if (fieldToChange != null)
                fieldToChange.SetValue(attribute, true); // resetting it to true
         }
      }
    }
}

推荐答案

您可以添加额外的TypeConverter,这将阻止编辑(只需放弃从string到destinationno类型的任何转换(即使destination也是一个字符串)).

在这之后,你可以在rutime中编辑ReadOnlyAttribute删除所有有线内容.

public class TestClass
{
    [Editor(typeof(CustomEditor), typeof(UITypeEditor))]
    [TypeConverter(typeof(ReadOnlyConverter))]
    public string MyText { get; set; }
}

public class ReadOnlyConverter : TypeConverter
{
    //just empty class
}

public class CustomEditor : UITypeEditor
{
    public override UITypeEditorEditStyle GetEditStyle(ITypeDescriptorContext context) 
           => UITypeEditorEditStyle.Modal;

    public override object EditValue(ITypeDescriptorContext context, IServiceProvider provider, object value)
    {
        var strVal = value as string;
        var svc = provider.GetService(typeof(IWindowsFormsEditorService)) as IWindowsFormsEditorService;

        using (var editorForm = new EditorForm())
        {
            editorForm.Value = strVal;

            svc.ShowDialog(editorForm);
            value = editorForm.Value;
        };
        

        return value;
    }
}

此外,您可能需要添加edditional check in EditValue,以确保服务可用,输入值为实string等等.

您还可以重写ReadOnlyConverter的成员以显式禁用字符串转换,而不依赖于默认实现.

.net相关问答推荐

为什么Linq中的运算符逻辑不匹配结果,当值为0或在VB. NET中没有

使用 MassTransit、.NET Core 和 RabbitMQ 的设计挑战

防止在 .NET 上构建路径中的反斜杠以进行跨平台部署

Unity 2.0:如何使用 Resolve 和 ResolverOverride?

将 DataRowCollection 转换为 IEnumerable

在目录中创建应用程序快捷方式

如何 Select 数据表中列的最小值和最大值?

找不到 Microsoft.Office.Interop Visual Studio

共享 AssemblyInfo 用于跨解决方案的统一版本控制

如何根据新的安全策略在 .Net 中发送邮箱?

注册 COM 互操作与使程序集 COM 可见

如何在 C# 7 中返回多个值?

Convert.ToBoolean 和 Boolean.Parse 不接受 0 和 1

形成两个列表并集的最简单方法

如何在 C# 中以编程方式安装 Windows 服务?

SqlBulkCopy 的推荐批量大小是多少?

使用没有catch块的try-finally块

我可以将构造函数参数传递给 Unity 的 Resolve() 方法吗?

C# 应用程序中的资源和嵌入式资源有什么区别?

什么时候使用 Tuple 和 KeyValuePair 比较好?