为什么ValueMember会覆盖空的DisplayMember

Epi*_*Kip 5 c# objectdatasource winforms

当我设置一个DataSource控件并想要使用.ToString()as时DisplayMember,我需要设置DisplayMember最后一个或ValueMember将覆盖它.

空字符串上的MSDN作为显示成员:

从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}";
    }
}
Run Code Online (Sandbox Code Playgroud)

形成:

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 = "";
Run Code Online (Sandbox Code Playgroud)

您可以通过制作新表格并添加2个组合框来尝试.

结果:

在此输入图像描述

结论和问题:

这可以通过以正确的顺序设置它们来轻松修复,但是这很容易出错,如果我使用实际属性作为DisplayMember而不是""/ ,它也不会显示此行为ToString.

我真的想知道为什么它会显示这种行为,如果我可以.ToString()显式设置为DisplayMember(代码清晰度).

Epi*_*Kip 2

我在参考源中搜索并发现了这一点:

if (!newValueMember.Equals(valueMember)) {
// If the displayMember is set to the EmptyString, then recreate the dataConnection
//
if (DisplayMember.Length == 0)
    SetDataConnection(DataSource, newValueMember, false);
Run Code Online (Sandbox Code Playgroud)

SetDataConnection方法签名:

private void SetDataConnection(object newDataSource, BindingMemberInfo newDisplayMember, bool force)
Run Code Online (Sandbox Code Playgroud)

这设置了一个新的 DisplayMember

displayMember = newDisplayMember;
Run Code Online (Sandbox Code Playgroud)

现在我们找到了问题的根源