4
public partial class TestConrol : UserControl
{
    public TestConrol()
    {
        InitializeComponent();
    }

    public override string ToString()
    {
        return "asd";
    }
}

public partial class Form1 : Form
{
    public Form1()
    {
        InitializeComponent();
    }

    private void Form1_Load(object sender, EventArgs e)
    {
        TestConrol tc1 = new TestConrol();
        comboBox1.Items.Add(tc1);

        TestConrol tc2 = new TestConrol();
        comboBox1.Items.Add(tc2);
    }
}

加载表单时,我看到组合框有两个名称为空的项目,而不是“asd”:/
但是如果我在公共类中覆盖 ToString(),则此工作有效,而不是从任何东西派生:

public class TestClass
{
    public override string ToString()
    {
        return "bla bla bla";
    }
}

public partial class Form1 : Form
{
    public Form1()
    {
        InitializeComponent();
    }

    private void Form1_Load(object sender, EventArgs e)
    {
        TestClass tcl = new TestClass();
        comboBox1.Items.Add(tcl);
    }
}

之后我在组合框中看到“bla bla bla”

4

5 回答 5

5

在您的控件中创建一个属性并将组合框的 DisplayMember 映射到该属性,它应该可以工作。

于 2013-04-08T18:09:26.653 回答
3

我试图理解源代码(!)。这不是一个简单的调用ToString()

有一个internal班级System.Windows.Forms.Formatter在做一些事情。它最终创建了一个转换器。这大致相当于说:

var conv = System.ComponentModel.TypeDescriptor.GetConverter(tc1.GetType());

tc1你的问题在哪里TestContol。现在,如果我们使用TestClass tclwhich 没有实现任何接口,这会给我们一个转换器,最终会调用ToString().

但是在这个例子中我们使用tc1, 它是一个System.ComponentModel.IComponent. 我们的conv因此变成了System.ComponentModel.ComponentConverter. 它使用Site. IComponent当我们说:

string result = conv.ConvertTo(tc1, typeof(string));

并且Site为空,我们得到""您在组合框中看到的空字符串。如果有一个Site它会用它Name来代替。

为了证明这一点,请将以下内容放入您的TestControl实例构造函数中:

public TestConrol()
{
    InitializeComponent();
    Site = new DummySite(); // note: Site is public, so you can also
                            // write to it from outside the class.
                            // It is also virtual, so you can override
                            // its getter and setter.
}

DummySite类似的东西在哪里:

class DummySite : ISite
{
    public IComponent Component
    {
        get { throw new NotImplementedException(); }
    }

    public IContainer Container
    {
        get { throw new NotImplementedException(); }
    }

    public bool DesignMode
    {
        get { throw new NotImplementedException(); }
    }

    public string Name
    {
        get
        {
            return "asd";  // HERE'S YOUR TEXT
        }
        set
        {
            throw new NotImplementedException();
        }
    }

    public object GetService(Type serviceType)
    {
        return null;
    }
}
于 2013-04-08T21:33:30.010 回答
1

使用comboBox1.Items.Add(tc1.ToString());代替comboBox1.Items.Add(tcl);

于 2013-04-08T18:10:34.427 回答
0

这对我有用:

comboBox1.FormattingEnabled = false
于 2015-11-03T07:37:08.250 回答
0

在您的UserControl中,添加一个属性,然后调用它FriendlyName,例如

namespace project
{
   public partial class CustomUserControl : UserControl
   {
      public CustomUserControl()
      {
         InitializeComponent();
      }

      public String FriendlyName { get => "Custom name"; }
   }
}

然后将DisplayMember你的属性设置ComboBox"FriendlyName",这样

myComboBox.DisplayMember = "FriendlyName";

对我来说,这是一个非常干净的解决方案,直觉告诉我这是预期的方法。

于 2020-07-01T08:42:14.627 回答