C#、WinForms ListBox - 以编程方式设置 DisplayMember 属性 - 可以添加文本吗?
C#, WinForms ListBox - Programatically setting DisplayMember property - can text be added?
我在 WinForms 中使用 ListBox 工作。我对 DisplayMember
属性.
有疑问
如果我理解正确 - 如果我没有提供 DisplayMember
属性 那么 ListBox 使用对象 ToString()
方法。但是,如果我指定 DisplayMember
,则 ListBox 将显示集合中对象的指定 属性。
但是,是否可以添加一些静态文本?
我的意思是,如果我的 属性 return 的名字是 "Dave",我有没有办法通过使用DisplayMember 属性 或其他方式?
我问是因为我正在使用的对象集合来自 class 我无法控制 - 因此我无法轻松创建新的 属性 或覆盖 ToString()
方法。
我曾短暂地考虑过扩展 class 并提供我自己的重写 ToString()
方法。但是在我的例子中,我需要能够将父 class 转换为子 class (这是不可能的)。我很快想到要编写一个静态方法来接受父 class 作为参数,复制其内容并 return 子 class 但我只是不知道这是否被认为是干净的和最佳实践。
有什么想法吗?
执行此操作的最佳方法是创建一个单独的包装器对象供您使用。您可以使该对象通用并在遇到相同问题的每个地方使用它。我要做的就是这样。
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;
}
}
}
我在 WinForms 中使用 ListBox 工作。我对 DisplayMember
属性.
如果我理解正确 - 如果我没有提供 DisplayMember
属性 那么 ListBox 使用对象 ToString()
方法。但是,如果我指定 DisplayMember
,则 ListBox 将显示集合中对象的指定 属性。
但是,是否可以添加一些静态文本?
我的意思是,如果我的 属性 return 的名字是 "Dave",我有没有办法通过使用DisplayMember 属性 或其他方式?
我问是因为我正在使用的对象集合来自 class 我无法控制 - 因此我无法轻松创建新的 属性 或覆盖 ToString()
方法。
我曾短暂地考虑过扩展 class 并提供我自己的重写 ToString()
方法。但是在我的例子中,我需要能够将父 class 转换为子 class (这是不可能的)。我很快想到要编写一个静态方法来接受父 class 作为参数,复制其内容并 return 子 class 但我只是不知道这是否被认为是干净的和最佳实践。
有什么想法吗?
执行此操作的最佳方法是创建一个单独的包装器对象供您使用。您可以使该对象通用并在遇到相同问题的每个地方使用它。我要做的就是这样。
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;
}
}
}