C# 当项目添加到ComboBox时,为什么重写的ToString()不返回我想要的内容?
加载表单时,我看到combobox有两个名称为空的项,而不是“asd”:/C# 当项目添加到ComboBox时,为什么重写的ToString()不返回我想要的内容?,c#,combobox,overriding,tostring,C#,Combobox,Overriding,Tostring,加载表单时,我看到combobox有两个名称为空的项,而不是“asd”:/ 但是,如果我在公共类中重写ToString(),而不是从任何东西派生,这将起作用: public partial class TestConrol : UserControl { public TestConrol() { InitializeComponent(); } public override string ToString() { re
但是,如果我在公共类中重写ToString(),而不是从任何东西派生,这将起作用:
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);
}
}
之后,我在combobox中看到“bla bla bla”在控件中创建一个属性,并将combobox的DisplayMember映射到该属性,它应该可以工作。使用
comboBox1.Items.Add(tc1.ToString())代码>而不是组合框1.Items.Add(tcl)代码>我试图理解源代码(!)。这不是对ToString()
的简单调用
有一个internal
类System.Windows.Forms.Formatter
在做一些事情。它最终创建了一个转换器。这大致相当于说:
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);
}
}
其中tc1
是您问题中的testcontrol
。现在,如果我们使用不实现任何接口的TestClass
tcl
,这将为我们提供一个最终调用ToString()
的转换器
但在本例中,我们使用了tc1
,它是一个。因此,我们的conv
成为System.ComponentModel.ComponentConverter
。它使用i组件的站点
。当我们说:
var conv = System.ComponentModel.TypeDescriptor.GetConverter(tc1.GetType());
而站点
为空,我们将得到您在组合框中看到的空字符串“
”。如果有一个站点
,它就会使用它的名称
要演示这一点,请将以下内容放入TestControl
实例构造函数中:
string result = conv.ConvertTo(tc1, typeof(string));
其中DummySite
类似于:
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.
}
这对我很有用:
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;
}
}
在UserControl
中,添加一个属性,并将其称为FriendlyName
comboBox1.FormattingEnabled = false
然后将组合框的DisplayMember
属性设置为“FriendlyName”
namespace project
{
public partial class CustomUserControl : UserControl
{
public CustomUserControl()
{
InitializeComponent();
}
public String FriendlyName { get => "Custom name"; }
}
}
对我来说,这是一个非常干净的解决方案,gut告诉我这是一种预期的解决方法。你在哪里调用ToString()
查看此站点,以获取示例/解释添加项目时combobox应该调用它,如果它适用于普通类,您是否可以对其中一个组合框属性执行受保护的覆盖,从e.argument参数访问它?
对不起,我不明白您在说什么:(我看到了同样的行为。它看起来像是System.Windows.Forms.ComboBox的内部代码
使用ToString
覆盖的对象不是System.Windows.Forms.UserControl
。我有点希望能够将comboBox1.SelectedItem强制转换回类实例…P.S.-1不是我的:P仍然感谢您的回答,如果newbieThanks问这个问题可能会有帮助,我正在尝试…但由于奇怪的原因,当我单击在属性列表中选择DisplayingMember时,它是空的,所以无需选择。哦,我只需要在那里键入,而不是选择。现在它可以工作了,谢谢!哦,哦,哦,但是如何处理CheckedListBox呢?:D没有DisplayingMember,但相同的问题有:嗯,很奇怪,我在PropertyList中看不到这一点。谢谢你解释这一点。你的答案值得接受,因为它确实回答了“为什么重写ToString()…”啊,我想这就是为什么他们在of组件中说。ToString
不应该被覆盖。我感谢你的水平和理解。谢谢你富有洞察力的回答!
myComboBox.DisplayMember = "FriendlyName";