【发布时间】: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<Customer> AvailableCustomers 属性。我必须将此设置为静态,以便 AvailableCustomersTypeConverter 可以访问它,因为它包含在属性中。
这很有效,因为它确实将客户限制在对象的其他部分中可用的客户。
但是,一旦内容失去焦点,选择就会变成空白:
请注意,我已经确认实际的对象引用仍然存在。引用没有损坏,只是停止在 UI 中正确显示。
我试图弄清楚即使在内容单元格失去焦点后如何让选定的客户正确显示。有人有什么想法吗?
【问题讨论】:
标签: c# .net wpf devexpress propertygrid