【发布时间】:2018-03-04 01:10:31
【问题描述】:
当我在控件上设置DataSource 并希望将.ToString() 用作DisplayMember 时,我需要最后设置DisplayMember,否则ValueMember 将覆盖它。
MSDN on empty string as display member:
继承自 ListControl 的控件可以显示不同类型的对象。如果指定的属性在对象上不存在或 DisplayMember 的值为空字符串 (""),则显示对象的 ToString 方法的结果。
要重现的代码:
类:
class SomeClass
{
public string PartA { get; set; }
public string PartB { get; set; }
public string WrongPart { get { return "WRONG"; } }
public override string ToString()
{
return $"{PartA} - {PartB}";
}
}
表格:
var testObj = new SomeClass() { PartA = "A", PartB = "B" };
comboBox1.DataSource = new [] { testObj };
comboBox1.DisplayMember = "";
comboBox1.ValueMember = "WrongPart";
comboBox2.DataSource = new[] { testObj };
comboBox2.ValueMember = "WrongPart";
comboBox2.DisplayMember = "";
您可以尝试制作一个新表单并添加 2 个组合框。
结果:
结论和问题:
这可以通过以正确的顺序设置它们来轻松解决,但这很容易出错,如果我使用实际属性作为 DisplayMember 而不是 ""/ToString,它也不会显示此行为。
我真的很想知道为什么它会显示这种行为,以及是否可以将 .ToString() 显式设置为 DisplayMember(为了代码清晰)。
【问题讨论】:
-
如果没有设置显示成员,这似乎是为了显示值成员。从您的代码中,我猜测这是在
ValueMember设置逻辑中触发的(类似于if(String.IsNullOrWhiteSpace(DisplayMember)) DisplayMember = value; -
@Flater 可行的答案,奇怪的是,如果文档说你需要一个空的 tostring(如果它的
null,他们应该使用值)我会检查参考源,谢谢你指出我正确的方向! -
-
检查了它使用的方法,这确实改变了 DisplayMember。我确实认为它的行为很奇怪:)
-
比起奇怪的行为,我认为这是一个过于简单的修复来实现默认显示值。他们应该在渲染时而不是在设置
ValueMember时评估DisplayMember的值。 setter 中的业务逻辑总是一个坏主意,这很好地说明了为什么它是一个坏主意。
标签: c# winforms objectdatasource