OP的答案:
据我了解,您正在使用值类型为字符串的字典。
这以详细信息模式向我显示字典中的值列表。
// Create dictionary.. Can be done somewhere else..
var dictionary = new Dictionary<int, string>();
dictionary.Add(1, "Item 1");
dictionary.Add(2, "Item 2");
// You can set up the column in the designer as well.
objectListView1.Columns.Add(new OLVColumn(title: "Items", aspect: "Value"));
// Initially tells OLV to use the dictionary as a datasource.
objectListView1.SetObjects(dictionary);
// .....
// Later on, you can add another item to the dictionary.
dictionary.Add(3, "Item 3");
// All you have to do now, is call .BuildList(), and your listview is updated.
// shouldPreserveState can be false if you want. I want it to be true. :)
objectListView1.BuildList(shouldPreserveState:true);
这不完全是“一行”,但如果您确实在设计器中设置了列,那么 SetObjects() 确实是激活它的那一行。您只需要记住在您的字典更改时调用 BuildList 即可。
回答@ElektroStudios
好的,所以出于某种原因,您想使用 ListViewItem 作为您的“数据容器”。正如@Grammarian 所指出的,这不是 OLV 的预期用途,但作为ListViewItem
具有属性的类与任何其他具有属性的类一样,这很容易做到。
这不是“单线”,但绝对不是write a 1000 lines model class... Just to add 1 string to a ListView
. 注意我指定了 2 种设置列的 getter 的方法。
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
// Items collection.
// Add your list view items to this.
// Note the fact that we have a different amount of subitems!!!
var items = new List<ListViewItem>
{
new ListViewItem(new []{"Hello", "Stack","Overflow"}),
new ListViewItem(new []{"ObjectListView is pretty damn neat!"}),
new ListViewItem(new []{"Pretty", "Cool"})
};
// These are set up by the WinForms Designer when I create OLV columns in the designer.
// Here, I am telling each column to use a custom getter, created by the SubItemGetter method.
// ensures the sub-items actually exist on each LVI.
olvColumn1.AspectGetter = SubItemGetter(0); // ListViewItem's first sub-item is the same as ListViewItem.Text. :)
olvColumn2.AspectGetter = SubItemGetter(1);
olvColumn3.AspectGetter = SubItemGetter(2);
// NOTE: I assume you know at design-time how many columns there are in your list view.
// Set them up as I've done above, or, if you want to be fancy..
for (int index = 0; index < objectListView1.Columns.Count; index++)
{
OLVColumn column = objectListView1.AllColumns[index];
column.AspectGetter = SubItemGetter(index);
}
// Tells OLV to use the items collection.
objectListView1.SetObjects(items);
// Sometime later, probably somewhere else in the code...
items.Add(new ListViewItem(new []{"I","Dont","Care","How","Many","SubItems","There","Is!"}));
// Tell OLV to rebuild!
objectListView1.BuildList(shouldPreserveState:true); // I'd like to preserve state, please :)
}
private AspectGetterDelegate SubItemGetter(int subItemIndex)
{
// This returns a method that gives OLV the string it needs to render each cell,
// while also making sure the sub item exists.
return rowObject =>
{
// Cast the row object to a ListViewItem. This should be safe.
var lvi = (ListViewItem) rowObject;
// Make sure the index is not out of range.
if (lvi.SubItems.Count <= subItemIndex)
return null;
// Return what needs to be displayed!
return lvi.SubItems[subItemIndex].Text;
};
}
}
这给了我一个像这样的默认 OLV(注意分组是可配置的!)..