Исключение приведения ObjectListView (для тестирования попаданий) - PullRequest
5 голосов
/ 25 октября 2009

Я использую Grammarian's ObjectListView. Я изменил свои старые списки на это, но все, что я делаю, это заполняю пункты. Но когда приложение запускается, и моя мышь находится над списком, оно немедленно выдает исключение:

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

Как это исправить?

Также я использую Win7, если это важно.

EDIT:

Я использую словарь. Похоже, мне нужно использовать метод SetObjects вместо добавления элементов.

Хорошо, это здорово, но я просто использую коллекцию dict.Value. Я не хочу изменять данные через просмотр списка, только показывать. Таким образом, у меня есть только 1 столбец и список всего, что является строками. Это возможно?

Буду признателен за небольшой образец.

Ответы [ 4 ]

2 голосов
/ 23 августа 2011

Что касается ответа Грамматика, то, что они не говорят вам, это:

Они говорят, что вам нужна всего одна строка, чтобы активировать ее, но вы обнаружите, что это головная боль и намного больше работы, чем она того стоит. Я весьма предлагаю вам придерживаться normal ListView, в противном случае вы обнаружите, что пишете класс модели из 1000 строк ... Просто добавьте 1 строку к ListView.

Только правда об этом ObjectListView бизнесе, прежде чем вы слишком углубитесь в него ...

Иди скачай пример и посмотри, мне проще просто использовать обычный ListView откровенно.

2 голосов
/ 08 января 2014

Ответ для ОП:

Насколько я понимаю, вы используете словарь, в котором типом значения является строка.

Показывает список значений в словаре в режиме сведений.

        // 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 в качестве «контейнера данных». Это не предназначено для использования в OLV, как указывает @Grammarian, но поскольку 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 по умолчанию, как этот (обратите внимание, что группировка настраивается!) ..

Form..

2 голосов
/ 26 октября 2009

Вы правы - вы должны использовать метод SetObjects() вместо добавления ListViewItems. В ObjectListView никогда не должно быть ListViewItems. Элемент управления отслеживает больше информации и поэтому нуждается в большем, чем обеспечивает ListViewItems.

Возможно, вы захотите прочитать страницу веб-сайта Getting Started , особенно раздел Unlearn, который вы должны .

ObjectListView имеет свой собственный форум , если вы хотите задать вопросы там.

0 голосов
/ 27 апреля 2014

Я получил аналогичную ошибку при попытке передать обычный ListView в виртуальном режиме в ListViewPrinter в OLV 2.7

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.

...