【问题标题】:PropertyGrid - Load dropdown values dynamicallyPropertyGrid - 动态加载下拉值
【发布时间】:2019-05-03 03:34:10
【问题描述】:

我已经尝试了各种各样的方法 - 大量使用 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

如何将“SystemTypes”作为从 mSystemTypes 集合动态填充的下拉选择器?例如。您选择“控制台”,它会使用匹配的 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 中使用它?),但我确信有一些解决方法。

【问题讨论】:

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


    【解决方案1】:

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

    示例 - VB.NET

    我想你有一个Product 类,有一个Category 类型的属性,你希望能够从List&lt;Category&gt; 中进行选择,它在运行时来自数据库之类的地方:

    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 的实例设置为PropertyGridSelectedObject 时,对于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);
        }
    }
    

    【讨论】:

      猜你喜欢
      • 2015-03-30
      • 2012-04-10
      • 2011-11-12
      • 1970-01-01
      • 2021-11-04
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多