PropertyGrid:仅为特定属性删除自定义数据类型的属性
Posted
技术标签:
【中文标题】PropertyGrid:仅为特定属性删除自定义数据类型的属性【英文标题】:PropertyGrid: remove a property of a custom data type only for a specific property 【发布时间】:2020-10-24 07:38:26 【问题描述】:首先:问题的措辞可能不准确,对此深表歉意。实际问题在所有代码 sn-ps 下方。 第二:代码是C#,但我通常用VB.NET写代码。
我有一个类LabelData
,其中包含用户绘制标签的视觉外观数据。简短的例子:
public class LabelData
public Color BackColor1 get; set;
public Color BackColor2 get; set;
public Color TextColor get; set;
public int TextAngle get; set;
public string Text get; set;
我的UserControl
使用LabelData
绘制了大量文本(我们称它们为小标签)。它看起来像这样(简化):
public class UserControl1
public LabelData Title get; set;
protected override void OnPaint(PaintEventArgs e)
// draw title here
LabelData currentLabel;
for (int i = 0; i <= 9; i++)
currentLabel = new LabelData();
currentLabel.BackColor1 = Color.Green;
currentLabel.BackColor2 = Color.YellowGreen;
currentLabel.TextAngle = 0;
currentLabel.Text = "Element" + i.ToString();
// draw text here
小标签的所有数据都在OnPaint
中定义。我不想要这个。我想到了一个用于像DataGridViewRowTemplate
这样的较小标签的模板。这也允许我为LabelData
实现ICloneable
。
这将变为:
public class UserControl1
public LabelData Title get; set;
public LabelData LabelTemplate get; set;
protected override void OnPaint(PaintEventArgs e)
LabelData currentLabel;
for (int i = 0; i <= 9; i++)
currentLabel = LabelTemplate.Clone();
currentLabel.Text = "Element" + i.ToString();
现在的问题:如何删除PropertyGrid
中LabelTemplate
属性(但不是Title
属性)的Text
-Property,因为此属性在OnPaint
反正?
PS:我尝试创建自定义设计器并覆盖 PreFilterProperties
以删除 Text
属性,但我无法将 DesignerAttribute
添加到 LabelTemplate
属性。
【问题讨论】:
【参考方案1】:由于您可能需要一个ExpandableObjectConverter 来呈现从您的LabelData
类对象分配的属性,因此您可以基于ExpandableObjectConverter
创建一个自定义类型转换器并从基类对象中删除属性,当您想要呈现这个时在特定情况下的对象不同。
例如,Title
和 Template
属性在 PropertyGrid 中显示为可展开的对象(因此您可以使用其特定的类型编辑器),Template
属性具有稍微不同的类型转换器,其中 GetProperties()
方法被覆盖以从基础 Class 对象中删除 Text
属性,因此它不会t 显示在 PropertyGrid 中:
Template 可扩展对象属性不显示 Text 属性作为它的同伴 Title 属性
C# 版本:
public class UserControl1
public UserControl1()
Template = new LabelData() ... ;
Title = new LabelData() ... ;
[TypeConverter(typeof(ExpandableObjectConverter))]
public LabelData Title get; set;
[TypeConverter(typeof(CustomExpandableConverter))]
public LabelData Template get; set;
// [...]
public class CustomExpandableConverter : ExpandableObjectConverter
public CustomExpandableConverter()
public override PropertyDescriptorCollection GetProperties(ITypeDescriptorContext context, object value, Attribute[] attributes)
var props = base.GetProperties(context, value, attributes)
.OfType<PropertyDescriptor>().Where(pd => pd.Name != "Text").ToArray();
return new PropertyDescriptorCollection(props);
VB.Net 版本:
Public Class UserControl1
Public Sub New()
Template = New LabelData()
Title = New LabelData()
End Sub
<TypeConverter(GetType(ExpandableObjectConverter))>
Public Property Title As LabelData
<TypeConverter(GetType(CustomExpandableConverter))>
Public Property Template As LabelData
'[...]
End Class
Public Class CustomExpandableConverter
Inherits ExpandableObjectConverter
Public Sub New()
End Sub
Public Overrides Function GetProperties(context As ITypeDescriptorContext, value As Object, attributes() As Attribute) As PropertyDescriptorCollection
Dim props = MyBase.GetProperties(context, value, attributes).
OfType(Of PropertyDescriptor)().
Where(Function(pd) Not pd.Name.Equals("Text")).ToArray()
Return New PropertyDescriptorCollection(props)
End Function
End Class
【讨论】:
我不知道你可以在TypeConverter
中过滤它们。这很棒。我过滤了更多属性,因为LabelData
class 实际上还有更多属性。非常感谢。以上是关于PropertyGrid:仅为特定属性删除自定义数据类型的属性的主要内容,如果未能解决你的问题,请参考以下文章