2015-09-07 6 views
0

Мне сложно создать класс, где я могу использовать ListBox для регистрации событий. Я знаю, что у меня есть тонны статей о том, что я спрашиваю о SO и google, но это я не сделал из этого. Поэтому я прошу немного помочь здесь:Регистрация событий пользовательского интерфейса с использованием списка

У меня есть три класса:

1: WinForm - Где мой список ящик помещается. Отсюда я передаю свой список в конструкторе FileEnumeratorClass().

2: FileEnumeratorClass - Получайте список и передавайте его в класс регистратора.

class FileEnumeratorClass { 
    UILogger logger; 
    /// <summary> 
    ///  ctor 
    /// </summary> 
    public FileEnumeratorClass (ListBox lbLog) 
    { 
     logger = new UILogger(lbLog); 
    } 

    /// <summary> 
    ///  Figures out what has changed between the src and destination 
    ///  What is currently implemented does not work......the solution is to compare SRC and DESTINATION for the first time. 
    ///  And verify with end user. 
    /// </summary> 
    public List<FileDetails> IdentifyChanges() 
    { 
     logger.AddToLog("Change detection initiated..."); 
     //Deletes any existing cached package. Assuming it is in incosistent form 
     logger.AddToLog("Cleaning up any cached local package."); 
     DeleteLocalPackage(); 
    } 
} 

3: UILogger

public class UILogger 
{ 
    public UILogger(ListBox lb) 
    { 
     lbLog = lb; 
    } 
    // This delegate enables asynchronous calls for setting 
    // the text property on a control. 
    delegate void AddToLogCallback(string text); 

    public void AddToLog(string message) 
    { 
     // InvokeRequired required compares the thread ID of the 
     // calling thread to the thread ID of the creating thread. 
     // If these threads are different, it returns true. 
     if (lbLog.InvokeRequired) 
     { 
      var d = new AddToLogCallback(AddToLog); 
      lbLog.Invoke(d, new object[] { message }); 
     } 
     else 
     { 
      // add this line at the top of the log 
      lbLog.Items.Insert(0, message); 

     } 

     // keep only a few lines in the log 
     while (lbLog.Items.Count > 1000) 
     { 
      lbLog.Items.RemoveAt(lbLog.Items.Count - 1); 
     } 
    }  
} 

Но приведенный выше код не работает, как ожидалось. Все отображаются, когда поток выполняется. Мне нужно вызвать методы AddToLog() в той же последовательности, в какой они записаны/вызваны в FileEnumeratorClass -> IdentifyChanges().

+0

Что делает ваша основная нить до завершения операции? – taffer

+0

Чувак, забудьте winforms, см. [Мой пример] (http://stackoverflow.com/a/16745054/643085) о том, как это сделать с молниеносной скоростью, поддержкой многопоточности и более богатым пользовательским интерфейсом. –

ответ

-1

Вам необходимо позвонить Control.Invalidate(), когда вы хотите, чтобы listbox обновил его содержимое, чтобы заставить listbox перерисовать себя. Обратите внимание: эти элементы управления являются потокобезопасными, что означает, что любой асинхронный или дочерний поток не должен обновлять какой-либо элемент управления пользовательского интерфейса. Используйте правильные обратные вызовы для потока пользовательского интерфейса и пусть поток пользовательского интерфейса обновляет элемент управления.

public List<FileDetails> IdentifyChanges() 
{ 
    logger.AddToLog("Change detection initiated..."); 
    //Deletes any existing cached package. Assuming it is in incosistent form 
    logger.AddToLog("Cleaning up any cached local package."); 

    //Invalidate the control to redraw. 
    logger.Invalidate(); 

    DeleteLocalPackage(); 
} 
+0

Нет, добавление элемента аннулирует элемент управления. Проблема в том, что у элемента управления нет времени обновляться до тех пор, пока операция не будет выполнена. Принудительное 'Refresh' будет обновлять элемент управления; однако его следует избегать. – taffer

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