PropertyGrid:仅针对特定 属性 删除自定义数据类型的 属性
PropertyGrid: remove a property of a custom data type only for a specific property
第一:问题的措辞可能不准确,请见谅。实际问题在所有代码片段下方。
第二:代码是用C#写的,但我一般写代码在VB.NET.
我有一个 class 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();
}
}
}
现在的问题:如何删除 Text
-属性 用于 LabelTemplate
属性(但不是对于 Title
属性) 在 PropertyGrid
中,因为这个 属性 在 OnPaint
中改变了吗?
PS:我尝试创建自定义设计器并覆盖 PreFilterProperties
以删除 Text
属性,但无法添加 DesignerAttribute
到 LabelTemplate
属性.
由于您可能需要 ExpandableObjectConverter 来呈现从 LabelData
Class object 分配的属性,因此您可以基于 [=13 创建自定义类型转换器=] 并从基础 Class Object 中删除属性,当您想在特定情况下以不同方式呈现此 object 时。
这里,例如,虽然 Title
和 Template
属性都显示为可扩展的 object 在 PropertyGrid 中(因此您可以使用其特定类型的编辑器编辑每个 属性 值),Template
属性不同的类型转换器,其中 GetProperties()
方法被覆盖以从基础 Class object 中删除 Text
属性,因此它不会显示在属性网格:
可扩展模板 object 属性 未将文本 属性 显示为标题 属性
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
第一:问题的措辞可能不准确,请见谅。实际问题在所有代码片段下方。
第二:代码是用C#写的,但我一般写代码在VB.NET.
我有一个 class 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();
}
}
}
现在的问题:如何删除 Text
-属性 用于 LabelTemplate
属性(但不是对于 Title
属性) 在 PropertyGrid
中,因为这个 属性 在 OnPaint
中改变了吗?
PS:我尝试创建自定义设计器并覆盖 PreFilterProperties
以删除 Text
属性,但无法添加 DesignerAttribute
到 LabelTemplate
属性.
由于您可能需要 ExpandableObjectConverter 来呈现从 LabelData
Class object 分配的属性,因此您可以基于 [=13 创建自定义类型转换器=] 并从基础 Class Object 中删除属性,当您想在特定情况下以不同方式呈现此 object 时。
这里,例如,虽然 Title
和 Template
属性都显示为可扩展的 object 在 PropertyGrid 中(因此您可以使用其特定类型的编辑器编辑每个 属性 值),Template
属性不同的类型转换器,其中 GetProperties()
方法被覆盖以从基础 Class object 中删除 Text
属性,因此它不会显示在属性网格:
可扩展模板 object 属性 未将文本 属性 显示为标题 属性
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