我使用ListBox在WinForms中工作。我对DisplayMember
属性有疑问。
如果我理解正确 - 如果我没有提供DisplayMember
属性,则ListBox使用对象ToString()
方法。但是,如果我指定DisplayMember
,则ListBox将显示集合中对象的指定属性。
但是,是否可以添加一些静态文本?
我的意思是,如果我的属性返回诸如“Dave”之类的名字,我是否有办法使用DisplayMember属性或其他方法为“First Name:Dave”添加前缀?
我问,因为我正在使用的对象集合来自我无法控制的类 - 因此我无法轻松创建新属性或覆盖ToString()
方法。
我简要地想过扩展课程并提供我自己的重写ToString()
方法。但是在我的情况下,我需要能够将父类强制转换为子类(这是不可能的)。我很快就想到编写一个静态方法,它接受父类作为参数,复制其内容并返回子类,但我不知道这是否被认为是干净的最佳实践。
有什么想法吗?
答案 0 :(得分:1)
执行此操作的最佳方法是创建一个您将使用的单独包装器对象。您可以将该对象设为通用对象,并在遇到相同问题的每个位置使用它。我会做的就是那样。
namespace Demo
{
using System;
public class Person
{
public string FirstName { get; set;}
public string LastName { get; set; }
}
public class ItemWrapper<T>
{
public T Item { get; private set; }
public string DisplayMember { get; private set; }
public ItemWrapper(T item, Func<T, string> displayFactory) {
if (item == null) {
throw new ArgumentNullException("item");
}
if (displayFactory == null) {
throw new ArgumentNullException("displayFactory");
}
this.Item = item;
this.DisplayMember = displayFactory(item);
}
public override string ToString() {
return this.DisplayMember;
}
/// <summary>
/// This method is just an example and should be removed
/// </summary>
public static void Example() {
var person1 = new Person() { FirstName = "Johny", LastName = "Bravo" };
var person2 = new Person() { FirstName = "Johny2", LastName = "Bravo" };
var person3 = new Person() { FirstName = "Johny3", LastName = "Bravo" };
var item1 = new ItemWrapper<Person>(person1, p => "First Name: " + p.FirstName);
var item2 = new ItemWrapper<Person>(person2, delegate(Person p) { return "First Name: " + p.FirstName; });
var item3 = new ItemWrapper<Person>(person3, DisplayFactory);
}
private static string DisplayFactory(Person p) {
return "First Name" + p.FirstName;
}
}
}
假设您有一个带有ListBox的表单。然后你就可以这样使用它:
namespace WindowsFormsApplication1
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
var p1 = new Person() {FirstName = "Johny", LastName = "Bravo"};
var p2 = new Person() {FirstName = "Alex", LastName = "Flo"};
var list = new List<ItemWrapper<Person>>
{
new ItemWrapper<Person>(p1, p => p.FirstName),
new ItemWrapper<Person>(p2, p => p.FirstName)
};
var bs = new BindingSource(list, "Item");
this.listBox1.DataSource = bs;
}
private void button1_Click(object sender, EventArgs e)
{
var person = this.listBox1.SelectedValue as Person;
}
}
}