c# - 不同派生类型的 WinForms 设计器属性

标签 c# .net winforms windows-forms-designer propertygrid

假设我有一个特定的类型,我想将其提供给 Windows 窗体设计器...

public class Style
{
    public CustomBrush Brush { get; set; }
}

CustomBrush 是这样实现的...

public abstract CustomBrush
{
    ...
}

public SolidCustomBrush : CustomBrush
{
    ...
}

public GradientCustomBrush : CustomBrush
{
    ...
}

有没有一种方法可以在设计时从 CustomBrush 派生的任何类型中进行选择,实例化所选类型的实例,并通过设计器对其进行修改?

到目前为止,我唯一能做到这一点的方法是使用 enum

enum BrushType
{
    Solid,
    Gradient
}

enum 发生变化时,Brush 属性下的类型也会发生变化,但我不喜欢这种方法...它很脏!

最佳答案

作为一个选项,您可以创建自定义 TypeConverter提供要在 PropertyGrid 中显示的标准值列表。

A type converter can provide a list of values for a type in a Properties window control. When a type converter provides a set of standard values for a type, the value entry field for a property of the associated type in a Properties window control displays a down arrow that displays a list of values to set the value of the property to when clicked.

由于您还希望能够在属性网格中编辑 CustomBrush 的子属性,因此您应该派生自 ExpandableObjectConverter .

结果

enter image description here

enter image description here

enter image description here

实现

创建一个 CustomBrushConverter 类并派生自 ExpandableObjectConverter .然后覆盖这些方法:

using System;
using System.ComponentModel;
using System.Linq; 
class CustomBrushConverter : ExpandableObjectConverter
{
    CustomBrush[] standardValues = new CustomBrush[] { new SolidCustomBrush(), new GradientCustomBrush() };
    public override bool CanConvertFrom(ITypeDescriptorContext context, Type sourceType)
    {
        if (sourceType == typeof(string))
            return true;
        return base.CanConvertFrom(context, sourceType);
    }
    public override object ConvertFrom(ITypeDescriptorContext context, System.Globalization.CultureInfo culture, object value)
    {
        var result = standardValues.Where(x => x.ToString() == value).FirstOrDefault();
        if (result != null)
            return result;
        return base.ConvertFrom(context, culture, value);
    }
    public override bool GetStandardValuesSupported(ITypeDescriptorContext context)
    {
        return true;
    }
    public override bool GetStandardValuesExclusive(ITypeDescriptorContext context)
    {
        return true;
    }
    public override StandardValuesCollection GetStandardValues(ITypeDescriptorContext context)
    {
        return new StandardValuesCollection(standardValues);
    }
}

然后用 TypeConverterAttribute 装饰 Brush 属性:

public class Style /*: Component */
{
    [TypeConverter(typeof(CustomBrushConverter))]
    public CustomBrush Brush { get; set; }
}

您可以覆盖 CustomBrush 类的 ToString 方法,以提供更友好的名称以显示在 PropertyGrid 的下拉列表中。例如:

public class GradientCustomBrush : CustomBrush
{
    public Color Color1 { get; set; }
    public Color Color2 { get; set; }
    public override string ToString()
    {
        return "Gradient";
    }
}

关于c# - 不同派生类型的 WinForms 设计器属性,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37931785/

相关文章:

c# - Sharpen捆绑物Sharpen.core的激活器sharpen.core.Sharpen无效

c# - 标签中未显示 Unicode 特殊字符

c# - 如何以编程方式禁用系统设备?

c# - 解决共享 transient 实例的位置

.net - 为什么 WsHttpbindings 给出错误为 "soap header action was not understood"而不是 basichttpbinding?

.net - 一个接口(interface)是否应该继承另一个接口(interface)

.net - 如何使用 linq 按自定义类型分组

winforms - MVP模式中使用Windsor caSTLe进行依赖注入(inject)的循环引用问题

c# - 如何在数据集上运行查询?

c# - 无法获取具有 CLSID {A9E69610-B80D-11D0-B9B9-00A0C922E750} 的组件的类工厂 de COM 错误 : 80040154 Class not Registered