【问题标题】:DevExpress WPF PropertyGridControl: Referencing objects in another part of the bound objectDevExpress WPF PropertyGridControl:在绑定对象的另一部分引用对象
【发布时间】:2020-06-30 19:19:26
【问题描述】:

我有一个复杂的对象,我试图在 DevExpress WPF PropertyGridControl 中显示它。该对象中嵌套了其他对象。一些嵌套对象引用其他嵌套对象,我想维护它们之间的引用链接(即我不想诉诸字符串或 id 来链接对象)。这是我正在处理的对象层次结构的一个人为示例:

public class OrderSystem
{
    public List<Customer> Customers { get; set; }
    public List<Order> Orders { get; set; }
}

public class Customer
{
    public string Name { get; set; }

    public override string ToString() => Name;
}

public class Order
{
    public Customer Buyer { get; set; }
}

我解决此问题的方法是使用自定义类型转换器装饰 Order 的 Buyer 属性,该类型转换器决定对象其他部分的可用客户:

public class Order
{
    [TypeConverter(typeof(AvailableCustomersTypeConverter))]
    public Customer Buyer { get; set; }
}

自定义类型转换器代码如下所示:

    public class AvailableCustomersTypeConverter : TypeConverter
    {
        public static List<Customer> AvailableCustomers { get; set; }

        public override StandardValuesCollection GetStandardValues(ITypeDescriptorContext context)
        {
            var customers = AvailableCustomers ?? new List<Customer>();
            var availableNames = AvailableCustomers.Select(c => c.Name).ToList();
            return new StandardValuesCollection(availableNames);
        }

        public override object ConvertFrom(ITypeDescriptorContext context, CultureInfo culture, object value) => DoConvert(value);

        public override object ConvertTo(ITypeDescriptorContext context, CultureInfo culture, object value, Type destinationType) => DoConvert(value);

        public override bool CanConvertTo(ITypeDescriptorContext context, Type destinationType) => destinationType == typeof(string) || destinationType == typeof(Customer);

        public override bool CanConvertFrom(ITypeDescriptorContext context, Type sourceType) => sourceType == typeof(string) || sourceType == typeof(Customer);

        private object DoConvert(object value)
        {
            if (value is string name)
            {
                if (AvailableCustomers != null)
                {
                    return AvailableCustomers.FirstOrDefault(c => c.Name == name);
                }
                else
                {
                    return string.Empty;
                }
            }
            else if (value is Customer customer)
            {
                return customer.Name;
            }
            else
            {
                throw new NotSupportedException($"{value.GetType().FullName}");
            }
        }
    }

当加载新的 OrderSystem 或 OrderSystem 的 Customers 集合更改时,将设置静态 List&lt;Customer&gt; AvailableCustomers 属性。我必须将此设置为静态,以便 AvailableCustomersTypeConverter 可以访问它,因为它包含在属性中。

这很有效,因为它确实将客户限制在对象的其他部分中可用的客户。

但是,一旦内容失去焦点,选择就会变成空白:

请注意,我已经确认实际的对象引用仍然存在。引用没有损坏,只是停止在 UI 中正确显示。

我试图弄清楚即使在内容单元格失去焦点后如何让选定的客户正确显示。有人有什么想法吗?

【问题讨论】:

    标签: c# .net wpf devexpress propertygrid


    【解决方案1】:

    我发现了这个问题,这源于我的错误想法,即 Customer 对象需要从字符串(它们的名称)来回转换,因为我认为这就是下拉框将显示的内容。但是,由于我在 Customer 对象(显示名称)上创建了 ToString() 覆盖,因此没有必要这样做。

    当我(或者更确切地说是我的同事)更改 AvailableCustomersTypeConverter 中的 GetStandardValues 方法以返回实际客户对象的列表而不仅仅是它们的名称时,突然事情开始起作用了。

    另外,因为我直接返回 Customer 对象,所以我不需要所有这些转换方法。更新后的 AvailableCustomersTypeConverter 代码如下所示:

    public class AvailableCustomersTypeConverter : TypeConverter
    {
        public static List<Customer> AvailableCustomers { get; set; }
    
        public override bool GetPropertiesSupported(ITypeDescriptorContext context) => true;
    
        public override bool GetStandardValuesSupported(ITypeDescriptorContext context) => true;
    
        public override bool GetStandardValuesExclusive(ITypeDescriptorContext context) => true;
    
        public override StandardValuesCollection GetStandardValues(ITypeDescriptorContext context)
        {
            return new StandardValuesCollection(AvailableCustomers ?? new List<Customer>());
        }
    }
    

    【讨论】:

      猜你喜欢
      • 2011-01-06
      • 1970-01-01
      • 2011-05-26
      • 1970-01-01
      • 2013-06-14
      • 1970-01-01
      • 2011-04-24
      • 2021-09-13
      • 1970-01-01
      相关资源
      最近更新 更多