Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/.net/24.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
PropertyGrid.NET winforms中的类型转换器重用_.net_Propertygrid_Typeconverter - Fatal编程技术网

PropertyGrid.NET winforms中的类型转换器重用

PropertyGrid.NET winforms中的类型转换器重用,.net,propertygrid,typeconverter,.net,Propertygrid,Typeconverter,我想问一下,在PropertyGrid中实现自定义下拉列表时,是否可以重用同一个TypeConverter,但使用不同的项。考虑下面的类型转换器,在属性网格中实现一个2项(狗/CAT)下拉列表。 Public Class MyList : Inherits System.ComponentModel.StringConverter Public items As String() = New String() {"dog", "cat"} Public Overloads O

我想问一下,在PropertyGrid中实现自定义下拉列表时,是否可以重用同一个TypeConverter,但使用不同的项。考虑下面的类型转换器,在属性网格中实现一个2项(狗/CAT)下拉列表。
Public Class MyList : Inherits System.ComponentModel.StringConverter
    Public items As String() = New String() {"dog", "cat"} 

    Public Overloads Overrides Function GetStandardValues(ByVal context As System.ComponentModel.ITypeDescriptorContext) As System.ComponentModel.TypeConverter.StandardValuesCollection
        Return New StandardValuesCollection(items)
    End Function

    Public Overloads Overrides Function GetStandardValuesSupported(ByVal context As System.ComponentModel.ITypeDescriptorContext) As Boolean
        Return True
    End Function

    Public Overloads Overrides Function GetStandardValuesExclusive(ByVal context As System.ComponentModel.ITypeDescriptorContext) As Boolean
        Return True
    End Function
End Class
此类型转换器的用途如下:

<TypeConverter(GetType(MyList))>
Public Class MyDogAndCatList
   ...
End Class

公共类MyDogAndCatList
...
末级
我现在想重用这个相同的TypeConverter MyList,但使用不同的列表项。我想用cow/sheep来代替dog/cat,然后定义复杂的数据类。大概是这样的:

cow_sheep = new MyList({"cow", "sheep"})
<TypeConverter(GetType(cow_sheep)), ...
cow\u sheep=新的MyList({“cow”,“sheep”})

您不能更改TypeConverterAttribute以向其添加内容,但可以向该属性添加任意数量的自定义属性,因此您可以创建自己的属性来保存自定义数据

下面是一些示例C#代码:

公共类动物
{
//这两个属性具有相同的TypeConverter,但它们使用不同的自定义属性
[TypeConverter(typeof(ListTypeConverter))]
[ListTypeConverter(新[]{“猫”、“狗”}]
公共字符串{get;set;}
[TypeConverter(typeof(ListTypeConverter))]
[ListTypeConverter(新[]{“cow”,“sheep”}]
公共字符串其他{get;set;}
}
//这是您的自定义属性
//注意属性只能使用常量(因为它们是在编译时添加的),所以不能在这里添加列表对象
[AttributeUsage(AttributeTargets.Property,AllowMultiple=false)]
公共类ListTypeConverterAttribute:属性
{
公共ListTypeConverterAttribute(字符串[]列表)
{
列表=列表;
}
公共字符串[]列表{get;set;}
}
//这是知道如何使用ListTypeConverterAttribute属性的类型转换器
公共类ListTypeConverter:TypeConverter
{
公共覆盖布尔GetStandardValuesSupported(ITypeDescriptorContext上下文)=>true;
公共覆盖标准值集合GetStandardValues(ITypeDescriptor上下文)
{
var list=新列表();
//上下文包含属性描述符
//属性描述符具有在属性上定义的所有自定义属性
//只需获取它(使用正确的null处理)
var choices=context.PropertyDescriptor.Attributes.OfType().FirstOrDefault()?.List;
如果(选项!=null)
{
列表。添加范围(选项);
}
返回新的标准值集合(列表);
}
}

您不能更改TypeConverterAttribute,但可以使用定义值列表的属性创建另一个自定义属性。然后您可以从自定义的TypeConverter中获取该属性及其属性。@Simon谢谢。你能用一些代码详细说明一下如何做到这一点吗?我对现代编程相当陌生,仍然停留在80年代的C语言中一半(但我正在变得更好:-)很难理解这个问题。类型转换器转换类型,在这两种情况下都是MyList。MyList对象具有不同的属性值决不重要。一定要让你的TypeConverter使用它。@Hans:目前我不知道如何为我的示例编写两个TypeConverter类。一个用于狗/猫列表,另一个用于牛/羊列表。每个类型转换器类必须包含所有被重写的类,即使唯一更改的是列表。如何只更改列表项,而不必编写新的TypeCOnverter类。这是我的问题。我希望这能让问题更清楚。为什么人们对这个问题投反对票?我来这里是因为我有问题。如果你投了反对票,那么至少告诉我为什么。每次否决票都会降低声誉,这限制了我的能力。非常感谢,这很有帮助。
public class Animals
{
    // both properties have the same TypeConverter, but they use different custom attributes
    [TypeConverter(typeof(ListTypeConverter))]
    [ListTypeConverter(new [] { "cat", "dog" })]
    public string Pets { get; set; }

    [TypeConverter(typeof(ListTypeConverter))]
    [ListTypeConverter(new [] { "cow", "sheep" })]
    public string Others { get; set; }
}

// this is your custom attribute
// Note attribute can only use constants (as they are added at compile time), so you can't add a List object here
[AttributeUsage(AttributeTargets.Property, AllowMultiple = false)]
public class ListTypeConverterAttribute : Attribute
{
    public ListTypeConverterAttribute(string[] list)
    {
        List = list;
    }

    public string[] List { get; set; }
}

// this is the type converter that knows how to use the ListTypeConverterAttribute attribute
public class ListTypeConverter : TypeConverter
{
    public override bool GetStandardValuesSupported(ITypeDescriptorContext context) => true;

    public override StandardValuesCollection GetStandardValues(ITypeDescriptorContext context)
    {
        var list = new List<string>();

        // the context contains the property descriptor
        // the property descriptor has all custom attributes defined on the property
        // just get it (with proper null handling)
        var choices = context.PropertyDescriptor.Attributes.OfType<ListTypeConverterAttribute>().FirstOrDefault()?.List;
        if (choices != null)
        {
            list.AddRange(choices);
        }
        return new StandardValuesCollection(list);
    }
}