【问题标题】:PropertyGrid: remove a property of a custom data type only for a specific propertyPropertyGrid:仅为特定属性删除自定义数据类型的属性
【发布时间】: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();
        }
    }
}

现在的问题:如何删除PropertyGridLabelTemplate 属性(但不是Title 属性)的Text-Property,因为此属性在OnPaint 反正?

PS:我尝试创建自定义设计器并覆盖 PreFilterProperties 以删除 Text 属性,但我无法将 DesignerAttribute 添加到 LabelTemplate 属性。

【问题讨论】:

    标签: c# .net vb.net winforms uitypeeditor


    【解决方案1】:

    由于您可能需要一个ExpandableObjectConverter 来呈现从您的LabelData 类对象分配的属性,因此您可以基于ExpandableObjectConverter 创建一个自定义类型转换器并从基类对象中删除属性,当您想要呈现这个时在特定情况下的对象不同。

    例如,TitleTemplate 属性在 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 中过滤它们。这很棒。我过滤了更多属性,因为LabelDataclass 实际上还有更多属性。非常感谢。
    猜你喜欢
    • 1970-01-01
    • 2017-09-12
    • 1970-01-01
    • 2012-01-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多