Функция срабатывает при добавлении нового элемента списка - PullRequest
0 голосов
/ 11 января 2020

Я продолжаю искать способ запуска функции в моем коде только после добавления элемента List, но не могу найти никакой информации.

Я думаю создать еще один список (см. Код ) со значениями List.Count, но вот так я попал в 15 списков ...

Есть ли лучший способ?

Спасибо

private List<int>       ListCountH;
...
ListCountH = new List<int>();
...
if (!LHsDmiAdd && b > 1 && HSwDMI[b-1] - HSwDMI[b] > 0.001 && HSwDMI[b-1] - HSwDMI[b-2] > 0.001)
{
  LastHSwDMI.Add(HSwDMI[b-1]);
  listCountLH = LastHSwDMI.Count;
  ListCountH.Add(listCountLH);   
  j++;
}
...
if (ListCountH[j-1] > ListCountH[j-2]) 
{
  // Logic triggered after ListCountH increase
}                          

Это, похоже, не работает:

var colL = new ObservableCollection<int>(ListCountL);
colL.CollectionChanged += (s, e) =>
{ 
   if (e.Action == System.Collections.Specialized.NotifyCollectionChangedAction.Add)
      // This code never triggers, but in the previous code it did after 
      // if (ListCountH[j-1] > ListCountH[j-2])                         
      if (k > 1 && c > 1 && (lowSwBarDiffA <= BarDiff || lowSwBarDiffB <= BarDiff))
        {
          if (!posDiv && ((LastLSwDMI[k-1] - LastLSwDMI[k-2] > 0.001 && LastLSwDMIprice[k-2] - LastLSwDMIprice[k-1] > TickSize)   
        || (LSwDMI[c-1] - LastLSwDMI[k-1] > 0.001 && LastLSwDMIprice[k-1] - LSwDMIprice[c-1] > TickSize)))  
            posDiv = true;  
         else
            posDiv = false;
         }
};              

Этот метод также выдает много ошибок компиляции, когда я пытаюсь объявить обработчик события:

public class Divergence5min : Strategy
{
   private MyList<int>      ListCountL, ListCountLastL;
   ...
  else if (State == State.Configure)                
  {
     ListCountL             = new MyList<int>();    
     ListCountLastL         = new MyList<int>();
  }

class MyList<T> : List<T> // Nested inside Divergence5min
{           
   public event Action<T> ItemAdded;            
   public new void Add(T obj)
   {                
     base.Add(obj);             
     if(ItemAdded != null)              
        ItemAdded.Invoke(obj);
   }
}

private void LookAfterLastLow()
{
    ListCountLastL.ItemAdded += AddItemEventHandler;
    void AddItemEventHandler()
    {   // The code I need executed after an item is added to ListCountLastL list
        if(listCountLL > 1)
        {       
            lastBarL = LastLSwDMIbar[k-1] + n;
            if (n <= 5)
            {
                newLastLowPrice = Lows[0].GetValueAt(lastBarL);
                if (newLastLowPrice < LastLSwDMIprice[k-1])
                {
                    LastLSwDMIprice[k-1] = newLastLowPrice;
                    newLastLowBar = lastBarL;
                    LastLSwDMIpriceBar[k-1] = newLastLowBar;
                    lowSwBarDiffB = Math.Abs(newLastLowBar - LastLSwDMIbar[k-1]);   
                    PrintLookAfterLow();                            
                }
                n++;
             }
        }               
    }
} 

Ответы [ 4 ]

6 голосов
/ 11 января 2020

Затем вы должны инкапсулировать "добавление" логики c в метод:

public void AddElementToList(int element)
{
  ListCountH.Add(element);
  // your logic goes here
}

или вы можете определить событие Add в своем классе и вызвать его при добавлении элемента в список, который снова следует заключить в отдельный метод:

public void AddElementToList(int element)
{
  ListCountH.Add(element);
  AddEvent?.Invoke();
}

Или вы можете написать перенос класса List, предоставляющий специальный метод Add и добавляющий событие, и использовать этот класс вместо List.

РЕДАКТИРОВАТЬ: Вы должны взглянуть на ObservableCollection:)

Пример использования:

// Have to include this using
using System.Collections.ObjectModel;

Использование:

var ol = new ObservableCollection<int>();
ol.CollectionChanged += (s, e) =>
{
  if (e.Action == System.Collections.Specialized.NotifyCollectionChangedAction.Add)
    Console.WriteLine("Item added!");
};
3 голосов
/ 11 января 2020

Вы можете превратить ваш List<int> в BindingList<int> следующим образом:

BindingList<int> boundList = new BindingList<int>(ListCountH);

BindingList<int> реализует IBindingList<int>, который имеет обработчик событий ListChanged. Поэтому создайте ListChangedEventHandler:

public void BoundList_ListChanged(object sender, ListChangedEventArgs e) {
    //use e.ListChangedType property to determine if a row was added
    if (e.ListChangedType == ListChangedType.ItemAdded) {
    ...Do Your Work Here...
    }
}

Затем добавьте обработчик в событие ListChanged вашего BindingList:

boundList.ListChanged += new ListChangedEventHandler(BoundList_ListChanged);

Редактировать: в зависимости от того, для чего вы используете список, текущий верхний ответ может быть лучше, поскольку ObservableCollection намного легче, если все, что вам нужно знать, это когда добавляется элемент. Однако BindingList имеет некоторые преимущества с элементами, которые поддерживают INotifyPropertyChanged (он может распространять события PropertyChanged элементов в его событие ListChanged), или если вам нужна поддержка списков Sorting, Searching или ReadOnly.

РЕДАКТИРОВАТЬ: сделало более ясным, что обработчик событий обрабатывает событие BindingList ListChanged, ранее я назвал функцию после другого списка, который не будет использоваться в этой реализации.

2 голосов
/ 11 января 2020

Вы можете создать свой собственный класс List (например: MyList<T>) и добавить событие, когда элемент добавляется в список.

class MyList<T> : List<T>
{
    //  Add an event that will be triggered after adding an item
    public event Action<T> ItemAdded;

    //  Override the add method
    public new void Add(T obj)
    {
        //  Call the parent add action
        base.Add(obj);

        //  Trigger the event
        ItemAdded?.Invoke(obj);
    }
}

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

Попробуйте событие:

static void Main()
{
    //  Create empty list
    MyList<string> list = new MyList<string>();

    //  Create a dummy action to display the added item
    void AddItemEventHandler(string item) => Console.WriteLine(item);

    //  Subscribe to the event
    list.ItemAdded += AddItemEventHandler;

    //  Add items to trigger the event
    list.Add("Hello");
    list.Add("Hola");
}

Вывод:

Hello
Hola
0 голосов
/ 21 января 2020

Ну ... я понял ... в конце концов

public class Divergence5min : Strategy
{
 private ObservableCollection <double> LastLSwDMI;
....
 LastLSwDMI = new ObservableCollection <double>();

...
 private void LookAfterLastLow()
 {
   LastLSwDMI.CollectionChanged += (s, e) => 
   {
     if (e.Action == System.Collections.Specialized.NotifyCollectionChangedAction.Add)
     {                  
        if(/*!LSwDMIbool &&*/ listCountLL > 1 && BarsInProgress == 0 && IsFirstTickOfBar)
        {       
           lastBarL = LastLSwDMIbar[k-1] + n;
           if (n <= 5)
           {
              newLastLowPrice = Lows[0].GetValueAt(lastBarL);
              if (newLastLowPrice < LastLSwDMIprice[k-1])
              {
                 LastLSwDMIprice[k-1] = newLastLowPrice;
                 newLastLowBar = lastBarL;
                 LastLSwDMIpriceBar[k-1] = newLastLowBar;
                 lowSwBarDiffB = Math.Abs(newLastLowBar - LastLSwDMIbar[k-1]);                                                          
              }
              n++;
            }               
         }
      }
    };
  }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...