【问题标题】:Disable Collection禁用收集
【发布时间】:2013-04-08 03:15:36
【问题描述】:

我有一个包含一些公共字段的类,我想在表单上的 PropertyGrid 中显示这些字段:

public class FileInfo
{
     ...

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

问题是我还想为此类的某些实例禁用 Collection,因此用户甚至无法进入其编辑器。而且我需要从代码中制作它,而不是从设计师那里。

即使我通过添加属性 [ReadOnly(true)] 将该字段设为只读,它也将允许用户通过按 (...) 进入其编辑器:

【问题讨论】:

  • 当你说设计师......你是指 Visual Studio、你的程序等吗?

标签: c# propertygrid


【解决方案1】:

如果您定义一个覆盖标准CollectionEditor 的自定义UITypeEditor,则可以这样做,如下所示:

    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);
        }
    }

【讨论】:

  • 谢谢,这正是我需要的。
【解决方案2】:

取决于您的程序设计。您可以使用继承。您并没有真正提供有关谁可以访问您的对象的信息……等等。由于缺乏其他细节,它需要在代码中而不是设计器中,这是一个简单的解决方案。或者你可能需要更强大的东西。

public class FileInfo
{
     //...
}

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

另一种选择可能是滚动您自己的 Collection 的继承副本,它会覆盖任何可以修改集合的方法。如果没有更多信息,而且集合是 ref 类型,我怀疑你会得到一个肯定的答案。

【讨论】:

    【解决方案3】:

    在属性顶部添加一个 ReadOnly 属性。

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

    还没有测试,希望它可以工作。

    取自this link

    【讨论】:

      【解决方案4】:

      添加一个布尔标志,指示该集合是否为只读:

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

      对于要禁用的实例,将 IsReadOnly 设置为 true。然后,您可以根据标志的状态启用/禁用您的 UI。

      【讨论】:

      • IsReadOnly 将显示为另一个属性,对 MessageInfos 没有意义。
      • @andark - 如果您只是将 IsReadOnly 设为公共字段而不是属性,它还会显示吗?已更新代码以反映此建议。
      • 如果它不是属性,它不会显示给用户,但我可以以任何方式进入 Collection 的编辑器。
      猜你喜欢
      • 2011-10-15
      • 2020-01-21
      • 1970-01-01
      • 2016-01-29
      • 1970-01-01
      • 2019-03-27
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多