Обработка события в разных экземплярах класса отдельно с использованием индексированного синглтона - PullRequest
1 голос
/ 30 января 2020

Я работаю со следующими одноэлементными классами: FormA, FormB и ShareFormDataEvent.


  • Когда я нажимаю кнопку на FormA, экземпляр из FormB создан.
  • На InitializeMethod из FormB я подписываюсь на ShareDataEvent, который объявлен в ShareFormDataEvent.
  • Затем я использую FormB.UniqueId в качестве ключа и сохраняю ShareDataEvent (с информацией о EventHandler, прикрепленной к нему) в словаре в ShareFormDataEvent классе.
  • Когда создается FormB, следующий шаг в FormA . Я использую FormB.UniqueId для доступа к словарю в EventHelper, чтобы получить Событие, которое прикреплено к Обработчику FormB , и вызвать его.

Это работает нормально, но когда я создаю новый экземпляр FormB, снова нажав кнопку в FormA и сохранив событие (с обработчиком) в словарь ShareFormDataEvent, а затем, вызывая событие для второго экземпляра FormB, второй экземпляр обрабатывает событие два раза.

Я знаю, что это происходит, потому что я храню один и тот же экземпляр события для двух экземпляров FormB. Сначала я хотел использовать UniqueId из FormB, чтобы отфильтровать «обработку» события для конкретного экземпляра c. Но я не понимаю.

Я поделюсь с вами кодом из трех классов. Я надеюсь, что кто-то может помочь, я буду очень благодарен.

public class FormA: IForm 
{
    buttonClick()
    {
        Application.ActivateForm(FormB);
        var FormB = Application.Forms.GetLastForm(FormB);
        ShareFormDataEvent.Instance[FormB.UniqueID]?.Invoke(_thisForm);
    }
}

public delegate void IFormEventHandler(IForm sender);

public sealed class ShareFormDataEvent
{
    private static readonly Lazy<ShareFormDataEvent> lazy = new Lazy<ShareFormDataEvent>(() => new ShareFormDataEvent());
    private readonly Dictionary<string, IFormEventHandler> _forms;

    public static ShareFormDataEvent Instance { get { return lazy.Value; } }

    private ShareFormDataEvent()
    {
        _forms = new Dictionary<string, IFormEventHandler>();
    }

    private void SetForm(string key, IFormEventHandler value)
    {
        _forms.Add(key, value);
    }

    private IFormEventHandler GetForm(string key)
    {
        IFormEventHandler value;
        _forms.TryGetValue(key, out value);
        return value;
    }

    public IFormEventHandler this[string index]
    {
        get { return GetForm(index); }
        set { SetForm(index, value); }
    }

    public IFormEventHandler CreateNewEvent(string id, object method)
    {
        IFormEventHandler a = new IFormEventHandler(form);

        return a;
    }
}
}


public class FormB: IForm 
{
    public override void OnInitialize()
    {
        base.OnInitializeComponent();
        ShareFormDataEvent.Instance.ShareData += new IFormEventHandler(ReceivingFormData); //Handler
        ShareFormDataEvent.Instance[_thisForm.UniqueID] = ShareFormDataEvent.Instance.ShareData;
    }
}  

Примечание:

Это SAP B1 Development, поэтому Я использую этот подход, потому что Framework слишком запечатан для передачи данных из одной формы в другую.

1 Ответ

0 голосов
/ 30 января 2020

Я разобрался с некоторым подходом:

Я создал другой класс для объявления события и делегата. Поэтому, когда инициализируется FormB, я создам новый экземпляр этого нового класса и сохраню его в словаре класса ShareFormDataEvent.

Я думаю, что это позволит мне в будущем добавлять больше событий, которые может (или не) использоваться формой, в зависимости от случая или цели формы.

вот мой код.

public class ShareDataEvent 
{
  public delegate void IFormEventHandler(IForm sender);
  public IFormEventHandler ShareData [get; set;}

}

public class FormB : IForm 
{
  public override void OnInitialize()
  {
    base.OnInitializeComponent();
    var shareDateEvent = new ShareDataEvent();
    ShareFormDataEvent.Instance[_thisForm.UniqueID] = 
    shareDataEvent; // First I add my new instance of ShareDataEvent class to the dictionary
    ShareFormDataEvent.Instance[ShareDataEvent].ShareData += new IFormEventHandler(ReceivingFormData); // Then I acces to that instance and attach the handler to the event.

  }
}  

Надеюсь, это поможет. И если есть лучший подход, я открыт для ... Ура!

...