PropertyGrid-动态加载下拉值

时间:2018-12-01 00:27:52

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

我已经尝试了各种方法-与TypeConverters等产生了很多混乱。因此,在这里我不会介绍所有内容。

因此,将问题简化为基本问题。考虑以下内容:

Imports LiteDB
Imports System.ComponentModel

Public Class mSystem

    <CategoryAttribute("General"), ReadOnlyAttribute(True)>
    Public Property ID As Integer

    Public Property ShortName As String = ""

    <BsonRef("mSystemTypes")>
    Public Property SystemType As mSystemType

End Class

Public Class mSystemType

    <CategoryAttribute("General"), ReadOnlyAttribute(True)>
    Public Property ID As Integer

    Public Property Name As String = "Default"
    Public Property Details As String = ""

End Class

如何从mSystemTypes集合动态填充“ SystemTypes”作为下拉选择器?例如。选择“控制台”,它将使用匹配的mSystemType更新mSystem。

我正在使用LiteDb,这可能会使事情变得有些困难,因为它不像其他情况下那样纯粹是“外键”的整数,而是一个完整的对象。

我需要维护'dbRef'方法,以确保数据关系的完整性。以防万一DBLite东西掉进了曲线球,下面的一些代码演示了它的用法:

Public Class dbCollecitons

    Public mSystems As LiteCollection(Of mSystem)
    Public mSystemTypes As LiteCollection(Of mSystemType)

    Private Sub Examples()

        Dim col As LiteCollection(Of mSystemType) = dbCollections.mSystemTypes
        Dim value as String = "Console"
        Dim q = col.FindAll.Where(Function(x) x.Name = value).First
        Console.Writeline(q.ID)

    End Sub

End Class

LiteDb.LiteCollection不能直接映射到ICollection(您是否在TypeConverter中使用它?),但是我敢肯定有一些解决方法。

1 个答案:

答案 0 :(得分:0)

简而言之,您需要创建一个支持标准值的新TypeConverter

示例-VB.NET

我想您有一个Product类,具有一个Category类型的属性,您希望能够从List<Category>中进行选择,该Public Class Product Public Property Id As Integer Public Property Name As String <TypeConverter(GetType(CategoryConverter))> Public Property Category As Category End Class Public Class Category Public Property Id As Integer Public Property Name As String Public Overrides Function ToString() As String Return $"{Id} - {Name}" End Function End Class 来自运行时数据库等地方,时间:

CategoryService

这是Public Class CategoryService Private list As List(Of Category) = New List(Of Category) From { New Category() With {.Id = 1, .Name = "Category 1"}, New Category() With {.Id = 2, .Name = "Category 2"}, New Category() With {.Id = 3, .Name = "Category 3"} } Public Function GetAll() As IEnumerable(Of Category) Return list End Function End Class 类,可以从您喜欢的任何地方加载类别:

CategoryConverter

下一步是创建Imports System.ComponentModel Public Class CategoryConverter Inherits TypeConverter Public Overrides Function GetStandardValues(ByVal context As ITypeDescriptorContext) As StandardValuesCollection Dim svc = New CategoryService() Return New StandardValuesCollection(svc.GetAll().ToList()) End Function Public Overrides Function GetStandardValuesSupported(ByVal context As ITypeDescriptorContext) As Boolean Return True End Function Public Overrides Function GetStandardValuesExclusive(ByVal context As ITypeDescriptorContext) As Boolean Return True End Function Public Overrides Function CanConvertFrom(ByVal context As ITypeDescriptorContext, ByVal sourceType As Type) As Boolean If sourceType = GetType(String) Then Return True Return MyBase.CanConvertFrom(context, sourceType) End Function Public Overrides Function ConvertFrom(context As ITypeDescriptorContext, culture As CultureInfo, value As Object) As Object If value IsNot Nothing AndAlso value.[GetType]() = GetType(String) Then Dim v = $"{value}" Dim id = Integer.Parse(v.Split("-"c)(0).Trim()) Dim svc = New CategoryService() Return svc.GetAll().Where(Function(x) x.Id = id).FirstOrDefault() End If Return MyBase.ConvertFrom(context, culture, value) End Function End Class ,它负责为下拉菜单提供值:

Product

然后,当您将SelectedObject的实例设置为PropertyGrid的{​​{1}}时,对于Category属性,您从列表中选择一个值。

示例-C#

以下是上面示例的C#版本:

public class Product
{
    public int Id { get; set; }
    public string Name { get; set; }
    [TypeConverter(typeof(CategoryConverter))]
    public Category Category { get; set; }
}
public class Category
{
    public int Id { get; set; }
    public string Name { get; set; }
    public override string ToString()
    {
        return $"{Id} - {Name}";
    }
}
public class CategoryService
{
    List<Category> list = new List<Category>{
        new Category() { Id = 1, Name = "Category 1" },
        new Category() { Id = 2, Name = "Category 2" },
        new Category() { Id = 3, Name = "Category 3" },
    };
    public IEnumerable<Category> GetAll()
    {
        return list;
    }
}
public class CategoryConverter : TypeConverter
{
    public override StandardValuesCollection GetStandardValues(ITypeDescriptorContext context)
    {
        var svc = new CategoryService();
        return new StandardValuesCollection(svc.GetAll().ToList());
    }
    public override bool GetStandardValuesSupported(ITypeDescriptorContext context)
    {
        return true;
    }
    public override bool GetStandardValuesExclusive(ITypeDescriptorContext context)
    {
        return true;
    }
    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, CultureInfo culture, object value)
    {
        if (value != null && value.GetType() == typeof(string))
        {
            var v = $"{value}";
            var id = int.Parse(v.Split('-')[0].Trim());
            var svc = new CategoryService();
            return svc.GetAll().Where(x => x.Id == id).FirstOrDefault();
        }
        return base.ConvertFrom(context, culture, value);
    }
}