2009-07-02 5 views
1

Как предотвратить запуск нескольких событий одного и того же типа, вызванных одним действием?Предотвращение многократного срабатывания событий от одного действия

Например, у меня есть ListView, содержащий некоторые элементы. Когда я выбираю или отменю выбор всех элементов, событие SelectedIndexChanged запускается один раз для каждого элемента. Скорее, я хотел бы получить одно событие, указывающее действие пользователя (выбор/отмена элементов), независимо от количества элементов.

Есть ли способ достичь этого?

+0

(ответил на комментарий) –

ответ

3

Вы не можете изменить код ListView, и подклассы его не предоставляют много вариантов.

Я бы предположил, что вы просто добавляете небольшую задержку (200 мс или тому подобное) к вашему коду - т. Е. Вы делаете расчет только через некоторое время после последнего обновления. Что-то вроде:

using System; 
using System.Windows.Forms; 
static class Program { 
    [STAThread] 
    static void Main() { 
     Application.EnableVisualStyles(); 
     ListView list; 
     TextBox txt; 
     Timer tmr = new Timer(); 
     tmr.Interval = 200; 
     Form form = new Form { 
      Controls = { 
       (txt = new TextBox { Dock = DockStyle.Fill, Multiline = true}), 
       (list = new ListView { Dock = DockStyle.Right, View = View.List, 
        Items = { "abc", "def" , "ghi", "jkl", "mno" , "pqr"}}) 
      } 
     }; 
     list.SelectedIndexChanged += delegate { 
      tmr.Stop(); 
      tmr.Start(); 
     }; 
     tmr.Tick += delegate { 
      tmr.Stop(); 
      txt.Text += "do work on " + list.SelectedItems.Count + " items" 
       + Environment.NewLine; 
     }; 
     Application.Run(form); 
    } 
} 
+0

Пример был бы очень оценен :) –

+0

Я вижу, но этот подход не мешает исполнению, но откладывает его. То, что я ищу, - это выполнить один раз и отбросить все ненужные казни.Как только что-то получится или отменено, я обновляю переменную, которая содержит общее состояние выбора, которое нужно делать ровно один раз за действие пользователя. –

+0

Вы должны отказаться от ** ранее ** действий - иначе вы не знаете, что вы действуете по правильным данным. Код, как показано, уменьшает все, кроме последнего. Таким образом, он действительно выполняется только один раз для каждого действия пользователя. –

1

Только мимо, придя к проблеме из немного другого направления. Например. подписать потеря фокуса.

В конце концов, приложение или среда выполнения не могут поднять событие на «все изменения выбора», фактически не используя что-то другое, потому что нет возможности для приложения предсказать, будет ли пользователь выполнять другой щелчок по элементу управления, пока он сохраняет фокус.

Даже используя фокус, пользователь может вернуться к этому элементу управления.

+0

Deselecting все детали осуществляется одним нажатием кнопки на фоне ListView, но срабатывает событие для каждого выключенного элемента тем не менее, что приводит к плохой производительности в виде вычисление, которое должно выполняться только один раз для каждого выбора/отмена выбора для каждого элемента вместо изменения выбора. –

+0

@Michael: почему бы не подписаться на события кликов и в событии клика прочитать текущий набор выбранных элементов? – Richard

+0

Хорошая идея, я попробовал, и она работает очень хорошо. Единственным недостатком является то, что при нажатии на фон ListView нет события Click, что означает, что мне нужно найти другой способ очистки другого вида. Возможно, я оставлю очищающее вещество в событии SelectedIndexChanged. –

0

Если ваш ListView находится в virtual mode, вы можете использовать VirtualItemsSelectionRangeChanged event. Это событие будет запущено только один раз для действия пользователя (выбор/дебекция).

+0

В чем заключается виртуальный режим? Никогда не слышал об этом. В MSDN говорится: «Чтобы использовать виртуальный режим, вы должны обработать событие RetrieveVirtualItem (...)». Должен ли я предоставлять другие функции для виртуального ListView, чтобы работать как не виртуальные ListView, к которым я привык? –

+0

«Виртуальный режим» означает, что ListViewItems создаются не сразу для всех элементов, а скорее по запросу, только для элементов, которые в настоящее время видны. Виртуальный режим особенно полезен, если у вас есть большие объемы данных, которые должны отображаться, и если вы храните данные где-то еще в своем приложении, кроме ListView. Таким образом, в основном два отличия состоят в том, чтобы хранить данные для элементов самостоятельно и обрабатывать событие RetrieveVirtualItem. – EFrank

Смежные вопросы