2013-08-25 2 views
1

Предположим, у меня есть 2 класса, класс А и класс В. Объект A (класса A) содержит некоторые объекты B (класса B). B имеют событие, а объект A подписывается делегатом, который выполняется, когда событие (любого из этих объектов B) создается.Использование (отправитель объекта) в делегате, подписанном на событие другого объекта

private void fooEventHandler(object sender, EventArgs e) 
{ 
... 
} 

После делать что-то в fooEventHandler (что должно быть сделано внутри), я хочу, чтобы сигнализировать объекта B, который вызвал событие результат того, что я сделал в fooEventHandler. Поэтому я делаю следующее:

private void fooEventHandler(object sender, EventArgs e) 
    { 
    ... 

     if (allOK) 
      ((classB)sender).isOK(); 
     else 
      ((classB) sender).isNotOK(); 
    } 

Так что я на самом деле с помощью отправителя вызова определенного метода на objectB после роста события. Я делаю все это, чтобы не переходить к objectB (в его конструкторе) некоторые объекты ObjectA, которые с дизайнерской точки зрения не должны быть в объекте B. Является ли это разумным способом решения проблемы? Обычно ли это используется (отправитель объекта) таким образом?

+2

isNotOK(). В качестве примера рассмотрим делегат CancelEventHandler. –

+0

Хм .. может быть, вы немного более конкретны? Я просматриваю CancelEventHandler, но я не понимаю, что вы имеете в виду ... –

+0

Если это ваше событие, лучше определить обработчик, который имеет класс B как аргумент вместо объекта – Vadim

ответ

1

Это решение, но я думаю, что это не лучший способ.

Вот еще одно решение

Шаг 1: - Создание класса унаследованы из через EventArgs и добавить в него некоторые свойства, которые определяют обработку, чтобы сделать в классе B

Для образца:

public class ClassBEventArgs : EventArgs 
{ 
    bool treatmentIsOK = false; 
} 

Шаг 2: В том же пространстве имен класса B создайте новое определение события делегата и используйте его для объявления события

Для образца:

namespace ClassBNameSpace 
{ 
    public delagate fooEventHandlerDelegate void (object sender, ClassBEventArgs e); 

    public ClassB 
    { 

    public event fooEventHandlerDelegate fooEventHandler; 

    ......... 

Step3: В ClassB поднять fooEventHandler событие с объекта через ClassBEventArgs. В обработчике событий ClassA задано правильное значение обработкиIsOK EventArgs.Когда обратный вызов события из ClassA в ClassB, вы можете использовать значение treatmentIsOK СВОЙСТВ

Для образца:

....... 
if (this.fooEventHandler != null) 
{ 
    ClassBEventArgs customEventArgs = new ClassBEventArgs(); 
    this.fooEventHandler (this,customEventArgs); 
    if (customEventArgs.treatmentIsOK) 
    { 
     this.isOK(); ==> Your code 
    } 
    else 
    { 
     this.isOK(); ==> Your code 
    } 
} 
....... 
+0

Это то, что @Hans рассказал в первом комментарии к вопросу. Это можно сделать легко с помощью 'CancelEventArgs', не так ли? Почему бы не использовать 'CancelEventArgs' –

+0

Конечно! вы можете использовать его. Мое решение предлагает только возможность более точно настроить EventArgs. – tdelepine

+0

Хотя ваше решение верно. Зачем изобретать велосипед? –

1

Почему бы не создать свой собственный класс EventArgs и разместить там B?

Как:

public class ClassBEventArgs : EventArgs 
{ 
    public classB classBObject { get; set; } 
} 
2

Я думаю, что вы сделаете свой класс А также в сочетании с классом B. Если все, что вам нужно, чтобы после обработки события вызывало определенный обратный вызов, затем передайте обратный вызов. Таким образом, вы можете, например, передать лямбда-выражения или передать методы классов, связанных с B, или что-то еще.

Так -

private void fooEventHandler(Action p_okCallback, Action p_notOkCallback) 
{ 
    ... 

    if (allOK) 
     p_okCallback(); 
    else 
     p_notOkCallback(); 
} 

или -

private void fooEventHandler(Action<bool> p_callback) 
{  
    ... 

    p_callback(allOk); 
} 

Если событие не находится под вашим контролем, вы могли бы сделать, как предложил Хелмером и наследоваться от EventArgs. Но опять же - я бы прошел в обратных вызовах, а не в самих классах.

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

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