Why overriden ToString() do not return what I want when item added to ComboBox?
c#, combobox, overriding, tostring
Solution
I tried to understand the source code(!). This is not a simple call to `ToString()`.
There's an `internal` class `System.Windows.Forms.Formatter` doing some stuff. It eventually creates a converter. This is roughly equivalent to saying:
var conv = System.ComponentModel.TypeDescriptor.GetConverter(tc1.GetType());
where `tc1` is the `TestContol` from your question. Now, had we used the `TestClass` `tcl` which doesn't implement any interfaces, this would have given us a converter which would eventually call `ToString()`.
But in this example we use `tc1`, and it is a `System.ComponentModel.IComponent`. Our `conv` therefore becomes a `System.ComponentModel.ComponentConverter`. It uses the `Site` of the `IComponent`. When we say:
string result = conv.ConvertTo(tc1, typeof(string));
and the `Site` is null, we get the empty string `""` you saw in your combo box. Had there been a `Site` it would have used its `Name` instead.
To demonstrate that, put the following into your `TestControl` instance constructor:
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.
}
where `DummySite` is something like:
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;
}
}
Problem
``` 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); } } ``` When form loaded, I see combobox has two items with empty names, instead of "asd" :/ But this work if I override ToString() in common class, not derived from anything: ``` 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); } } ``` After that I see in combobox "bla bla bla"