ObjectListView强制转换exception(用于命中测试)

我正在使用Grammarian的ObjectListView。 我将旧的列表视图更改为了,但我所做的只是填写项目。 但是当应用程序启动并且我的鼠标位于列表视图上时,它会立即抛出exception:

System.InvalidCastException was unhandled Message="Unable to cast object of type 'System.Windows.Forms.ListViewItem' to type 'BrightIdeasSoftware.OLVListItem'." Source="ObjectListView" 

如何解决这个问题?

如果这很重要,我也使用Win7。

编辑:

我用字典。 看起来我需要使用SetObjects方法而不是添加项目。

好的,这很棒,但我只是使用dict.Value集合。 我不想通过listview修改数据,只显示。 所以我只有一列,列出了所有字符串。 这可能吗?

我很感激一个小样本。

你是对的 – 你应该使用SetObjects()方法而不是添加ListViewItems 。 在ObjectListView中,永远不应该有ListViewItems. 控件跟踪更多信息,因此需要的不仅仅是ListViewItems提供的信息。

您可能需要阅读网站的“ 入门”页面,尤其是“ 必须忘记”部分。

如果你想在那里提问,ObjectListView确实有自己的论坛 。

关于Grammarian的答案,他们没有告诉你的是这个。

他们告诉你,你只需要一行来激活它,但你会发现它很头疼,而且还有很多工作值得。 我强烈建议你坚持使用普通的 ListView ,否则你会发现自己编写了一个1000行的模型类…只需要向ListView添加1个字符串。

关于这个ObjectListView业务的真相,在你看了太多之前……

下载示例并看看,我发现坦率地使用普通的ListView更容易。

OP的答案:

据我所知,您正在使用值类型为字符串的字典。

这在“详细信息”模式下显示了字典中的值列表。

  // Create dictionary.. Can be done somewhere else.. var dictionary = new Dictionary(); 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 { 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(注意分组是可配置的!)..

形成..

尝试将虚拟模式下的普通ListView传递给OLV 2.7中的ListViewPrinter时,我遇到了类似的错误

 The error occurred here: #if !WITHOUT_OBJECTLISTVIEW ///  /// Get the nth item from the given listview, which is in virtual mode. ///  /// The ListView in virtual mode /// index of item to get /// the item override protected ListViewItem GetVirtualItem(ListView lv, int n) { // Invalid Cast happens here return ((VirtualObjectListView)lv).MakeListViewItem(n); } 

它使用objectlistview按预期工作。 除了使用objectlistview之外没有解决方案。