5

Grammarian の ObjectListView を使用しています。古いリストビューをそれに変更しましたが、項目を入力するだけです。しかし、アプリが起動し、マウスがリストビューの上にあると、すぐに次の例外がスローされます。

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 コレクションを使用しているだけです。リストビューでデータを変更したくありません。表示するだけです。したがって、列は1つしかなく、そこに文字列であるすべてをリストします。これは可能ですか?

小さなサンプルをいただければ幸いです。

4

4 に答える 4

3

SetObjects()その通りです。追加するのではなく、メソッドを使用する必要がありますListViewItemsListViewItems.コントロールはより多くの情報を追跡するため、ListViewItems が提供する以上のものを必要とします。

Web サイトのGetting Startedページ、特にUnlearn you mustセクションを読むことをお勧めします。

そこで質問したい場合は、ObjectListView に独自のフォーラムがあります。

于 2009-10-26T07:52:00.563 に答える
2

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 が得られます (グループ化は構成可能であることに注意してください!)。

形..

于 2014-01-08T18:55:26.647 に答える
1

グラマリアンの答えに関して、彼らがあなたに教えていないのはこれです。

彼らは、それをアクティブ化するために必要な行は 1 つだけであると言いますが、それは頭痛の種であり、その価値よりもはるかに多くの作業が必要であることがわかります。通常の. _ _ ListView _ListView

ObjectListView調べすぎる前に、このビジネスについての真実だけを...

ListView例をダウンロードして見てください。率直に言って、法線を使用する方が簡単です。

于 2011-08-23T03:46:23.880 に答える
0

仮想モードの通常の ListView を OLV 2.7 の ListViewPrinter に渡そうとすると、同様のエラーが発生しました。

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

objectlistview で期待どおりに動作します。objectlistview を使用する以外に解決策はありません。

于 2014-04-26T21:06:31.103 に答える