是否有一个属性我可以在我的类中使用来告诉 DataGridView 在绑定到 List<MyClass> 时不要为其创建列

Posted

技术标签:

【中文标题】是否有一个属性我可以在我的类中使用来告诉 DataGridView 在绑定到 List<MyClass> 时不要为其创建列【英文标题】:Is there an Attribute I can use in my class to tell DataGridView not to create a column for it when bound to a List<MyClass> 【发布时间】:2010-11-07 04:53:54 【问题描述】:

我有这样的课:

private class MyClass 
  [DisplayName("Foo/Bar")]
  public string FooBar  get; private set; 
  public string Baz  get; private set;       
  public bool Enabled;

当我创建 List&lt;MyClass&gt; 并将其分配给 DataGridViewDataSource 时,网格会显示两列,“Foo/Bar”和“Baz”。这就是我想要发生的事情。

它目前有效,因为 Enabled 是一个字段,而不是一个属性 - DataGridView 只会选择属性。然而,这是一个肮脏的黑客。

我也想将 Enabled 设为属性,但仍将其隐藏在 DataGridView 中。

我知道我可以在绑定后手动删除该列..但这并不理想。

是否有类似于 DisplayName 的属性,我可以用它来标记属性? [Visible(false)] 之类的东西?

【问题讨论】:

【参考方案1】:

[Browsable(false)] 将隐藏 DataGridView 的属性。

视觉设计器通常会在“属性”窗口中显示那些 没有可浏览属性或标有 BrowsableAttribute 构造函数的可浏览参数设置为 true。 这些成员可以在设计时进行修改。标有 BrowsableAttribute 构造函数的可浏览参数设置为 false 是 不适合设计时编辑,因此不适合 显示在视觉设计器中。默认为真。

【讨论】:

这很有趣,在我看来 [Bindable(false)] 应该可以工作,并且 Browsable(根据帮助)仅定义属性是否显示在 PropertyGrid 中。但是 Bindable(false) 被 DataGridView 忽略了。 我同意,但是在阅读(并重新阅读)框架设计指南 (amazon.com/Framework-Design-Guidelines-Conventions-Development/…) 之后,我发现设计师并不总是遵循自己的规则(有时会做一些事情没有意义)。 所有这些控件都使用System.ComponentModel.PropertyDescriptor,因此它们使用相同的逻辑来包含/排除成员。 ComponentModel 类是可定制的,但这样做很少见,因为它的工作量很大。【参考方案2】:

我一直很高兴地没有意识到 System.ComponentModel 装饰器属性像 BrowsableAttribute 和它的 kin 与绑定到 PropertyGrid 之外的任何东西有关。 (facepalm) 我喜欢 C-Pound Guru 的方法,因为它让你的 GUI 比我过去所做的更松散耦合。

只是换个角度来看,我长期使用的方法是在 DataGridView 中预先定义列,可以通过编程方式或通过表单设计器。执行此操作时,您可以将每列的 DataPropertyName 设置为您的属性的名称。唯一的技巧是您需要将 DataGridView 的 AutoGenerateColumns 属性设置为 false,否则 DGV 将完全忽略您手动创建的列。请注意,无论出于何种原因,AutoGenerateColumns 属性都隐藏在表单设计器的属性网格中……不知道为什么。我看到这种方法的一个优点是您可以预先设置列格式等 - 您不必绑定然后去调整列渲染/大小设置。

这是我的意思的一个例子:

_DGV.AutoGenerateColumns = false;
DataGridViewTextBoxColumn textColumn = new DataGridViewTextBoxColumn();
textColumn.DataPropertyName = "FooBar";
textColumn.HeaderText = "Foo/Bar"; // may not need to do this with your DisplayNameAttribute
_DGV.Columns.Add(textColumn);
textColumn = new DataGridViewTextBoxColumn();
textColumn.DataPropertyName = "Baz";

List<MyClass> data = GetMyData();
_DGV.DataSource = data;

【讨论】:

我很高兴看到我不是唯一一个无法通过表单设计器访问AutoGenerateColumns 属性的人。 我当然认为这是最好的答案。一个代码行就可以完成所有工作,而不是重构我所有的自定义类......

以上是关于是否有一个属性我可以在我的类中使用来告诉 DataGridView 在绑定到 List<MyClass> 时不要为其创建列的主要内容,如果未能解决你的问题,请参考以下文章

当我的类中有属性具有默认构造函数来提供值自动映射器时,如何映射?

python中方法和属性之间的区别

为啥我不能在我的类中内联函数? [复制]

使用 LINQ 从具有嵌套数组的类中获取子属性值和父属性值

我可以在属性中指定路径以将我的类中的属性映射到我的 JSON 中的子属性吗?

元类中的属性()设置器问题