Вопрос по wpf, events, c# – WPF: вызвать событие, когда элемент добавлен в ListView.

15

Я работаю над WPF и использую ListView, и мне нужно вызвать событие, когда в него добавлен элемент. Я пробовал это:

var dependencyPropertyDescriptor = DependencyPropertyDescriptor.FromProperty(ItemsControl.ItemsSourceProperty, typeof(ListView));
        if (dependencyPropertyDescriptor != null)
        {
               dependencyPropertyDescriptor.AddValueChanged(this, ItemsSourcePropertyChangedCallback);
        }

.....

 private void ItemsSourcePropertyChangedCallback(object sender, EventArgs e)
    {
         RaiseItemsSourcePropertyChangedEvent();
    }

Но, кажется, работает только тогда, когда вся коллекция изменена, я прочитал этот пост: События зажжены когда-вещь-это добавленные к ListView, но лучший ответ относится только к списку. Я пытался изменить код на ListView, но я не смог этого сделать.

Я надеюсь, что вы можете помочь мне. Заранее спасибо

В комментариях к ответу на вопрос, который вы публикуете, вы найдете «Изменил мой код выше, чтобы сделать его более понятным. Также это должно работать с любым ItemsControl (ListBox или ListView)». - Какие проблемы у вас есть, в частности? Slugart
@ Slugart Спасибо за ваш ответ, у меня проблема в том, что методBeginInvoke не принимает декларацию в качестве примера. Это говорит о том, чтоDispatcherPriority не существуе Dante

Ваш Ответ

2   ответа
47

Обратите внимание, это работает только для списка просмотра WPF!

После некоторых исследований я нашел ответ на свой вопрос, и это действительно легко:

public MyControl()
{
    InitializeComponent();
    ((INotifyCollectionChanged)listView.Items).CollectionChanged +=  ListView_CollectionChanged;
}

private void ListView_CollectionChanged(object sender, NotifyCollectionChangedEventArgs e)     
{
    if (e.Action == NotifyCollectionChangedAction.Add)
    {
      // scroll the new item into view   
      listView.ScrollIntoView(e.NewItems[0]);
    }
}

На самом деле,NotifyCollectionChangedAction enum позволяет вашей программе информировать вас о любых изменениях, таких как: Добавить, Переместить, Заменить, Удалить и Сбросить.

Это не работает для меня. Я получаю Невозможно привести объект типа 'ListViewItemCollection' к типу 'System.Collections.Specialized.INotifyCollectionChanged'. Arvo Bowen
Для всех, кому интересно,ListView.Items имеет типItemsCollection. Это наследуется отCollectionView который реализуетINotifyCollectionChanged. Глядя на MSDN, это было верно для .NET 3.0 - 4.6. @ArvoListViewItemCollection только реализуетIList, ICollection, IEnumerable и не наследует ни от чего, следовательно, ваше исключение. Darren Hale
Работает с WPF Listbox тоже. Если observablecollection <string> привязана, первое вхождение будет введено в View! Поэтому, если одно и то же значение может встречаться несколько раз, используйте класс с одним свойством для привязки (observablecollection <myclass>) и соответственно установите DisplayMemberPath. dba
-1

Примечание: это решение предназначено для WinForms ListView.

В моем случае я остановился на дороге с двумя вариантами выбора ...

(1) Создайте пользовательский элемент управления ListView, который наследует класс ListView. Затем добавьте новое событие, которое будет вызвано, когда любой элемент добавлен, удален или ListView очищен. Этот путь казался действительно грязным и долгим. Не говоря уже о другой большой проблеме, что мне нужно будет заменить все мои оригинальные ListViews на недавно созданный пользовательский элемент управления ListView. Вот и прошел я эт

(2) При каждом вызове добавления, удаления или очистки представления списка я также вызывал другую функцию, имитирующую событие CollectionChanged.

Создайте новое событие как функцию ...

private void myListViewControl_CollectionChanged(object sender, NotifyCollectionChangedEventArgs e)
{
    //The projects ListView has been changed
    switch (e.Action)
    {
        case NotifyCollectionChangedAction.Add:
            MessageBox.Show("An Item Has Been Added To The ListView!");
            break;
        case NotifyCollectionChangedAction.Reset:
            MessageBox.Show("The ListView Has Been Cleared!");
            break;
    }
}

Добавить элемент в ListView в другом месте ...

ListViewItem lvi = new ListViewItem("ListViewItem 1");
lvi.SubItems.Add("My Subitem 1");
myListViewControl.Items.Add(lvi);
myListViewControl_CollectionChanged(myListViewControl, new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Add, lvi, lvi.Index));

Очистить ListView в другом месте ...

myListViewControl.Items.Clear();
myListViewControl_CollectionChanged(myListViewControl, new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Reset));
Довольно странно, что решение Данте не работает для тебя, особенно когда ты обходишься ...INotifyCollectionChanged. ((INotifyCollectionChanged)MyList.Items).CollectionChanged += MyListChanged работал на меня. Вы уверены, что поставили круглые скобки в нужных местах? Mathieu Guindon
Может быть, это как-то связано с WPF, я этим не пользуюсь, я использую WinForms. Не уверен, что я знаю только то, что все пространства имен учтены, и все ссылки отлично работают с этими объектами / типами. Я даже не совсем понимаю, как вы можете привести коллекцию listView.Items к INotifyCollectionChanged (не говоря, что это невозможно, я просто не понимаю). Все остальное выглядит хорошо, кроме этой части. Я более чем готов попробовать что-нибудь, если вы мне скажете. Но в моем нынешнем виде VS 2010 говорит нет! ;) Arvo Bowen
WinForms и WPF - два совершенно разных зверя; WinFormsListView имеетничего таког делать с WPFListView! WPFListViewItemCollection реализуетINotifyCollectionChanged; это позволяет мощным возможностям связывания данных WPF обнаруживать изменения в списке и [почти] Автомагически держать все в курсе. Вы должны подумать о том, чтобы оставить WinForms позади и попробовать WPF - как только вы его освоите, вы никогда не будете оглядываться назад! :) Mathieu Guindon
Благодарность! Принято к сведению. Я отредактировал ответ Данте по нескольким причинам (добавив примечание вверху для разработчиков на чистом C #, таких как я). Как только редактирование принято, оно получает голос от меня. Скоро попробую WPF! ;) Мне тоже нужно перейти с 2010 на 2013 год. хе-хе Arvo Bowen
Нет проблем, кроме вопроса уже помечен МОФ ... (не мое отрицательное мнение) Mathieu Guindon

Похожие вопросы