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);
これは厳密には「1 行」ではありませんが、デザイナーで列を設定する場合、SetObjects() は実際にはその 1 行でアクティブ化されます。辞書が変更されるたびに BuildList を呼び出すことを忘れないでください。
@ElektroStudios への回答
さて、何らかの理由で ListViewItem を「データ コンテナー」として使用したいとします。@Grammarian で指摘されているように、これは OLV の意図した使用法ではありませんが、ListViewItem
プロパティを持つ他のクラスと同様に、プロパティを持つクラスと同様に、これは簡単に実行できます。
これは「ワンライナー」ではありませんが、間違いなくwrite a 1000 lines model class... Just to add 1 string to a ListView
. 列のゲッターを設定する 2 つの方法を指定したことに注意してください。
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 が得られます (グループ化は構成可能であることに注意してください!)。
