2014-12-21 5 views
0

У меня есть графический интерфейс C# WPF в ProjectA. Я поднимаю событие в ProjectA и хочу подписаться/ответить на это событие из ProjectB, который является dll, который ничего не знает о ProjectA. ProjectA имеет ссылки на объекты в ProjectB, но не наоборот.Как подписаться на событие C# GUI из ProjectA в dll в ProjectB

Например, пользователь нажимает кнопку в ProjectA. Внутри обработчика button_Click() ProjectA он вызывает UserClickedButtonX (это, e). ProjectB должен подписаться на UserClickedButtonEvent и обрабатывать его, когда событие поднято.

Код ниже не работает, поскольку ProjectB не знает о «MainWindow» в ProjectA. Заранее спасибо!

In ProjectA (Mainwindow.xaml.cs): 
     private void buttonX_Click(object sender, RoutedEventArgs e) { 
      OnUserClickedButtonXEvent(new EventArgs()); 
     } 

     public static event UserClickedButtonXEventHandler UserClickedButtonXEvent; 
     public virtual void OnUserClickedButtonXEvent(EventArgs e) { 
      if (UserClickedButtonXEvent!= null) 
       UserClickedButtonXEvent(this, e); 
     } 

In Project B (dll): 
      MainWindow.UserClickedButtonXEvent+= new UserClickedButtonXEventHandler(UserClickedButtonXFunction); 

     void UserClickedButtonXFunction(object source, EventArgs e) { 
      Console.WriteLine("User clicked Button X on the GUI in another project!"); 
     } 
+0

Рассмотрите решение, предложенное @ScottNimrod, но не используйте его реализацию «EventAggregator». Возьмите «EventAggragator» Prism и «PubSubEvent». Подробнее [здесь] (http://compositewpf.codeplex.com/). – dymanoid

+0

Чувак, почему бы не просто расширить пример, который я предоставил при необходимости? –

ответ

0

Вы должны быть в состоянии поставить эту строку в Projecta (. Например MainWindow застройщик):

MainWindow.UserClickedButtonXEvent += ProjectB.ClassB.UserClickedButtonXFunction; 

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

+0

Хотя другие ответы/комментарии более общие/надежные, я отметил это как решение, так как он достигает желаемого поведения и гораздо проще реализовать. Спасибо всем! – nb1forxp

0

Рассмотрите возможность использования EventAggregator для разделения классов друг от друга в отношении публикации событий \ subscribe.

Этот шаблон использует сообщения (т. Е. Строки), которые издатели и подписчики могут использовать, не зная друг о друге.

[TestMethod] 
public void eventaggregator() 
{ 
    // Setup 
    var subscription = "my_subscription"; 
    bool messageReceived = false; 

    EventAggregator.Instance.Register(subscription, (parameter) => 
     { 
      // Logic goes here... 
      messageReceived = true; 
     }); 

    // Test 
    EventAggregator.Instance.Publish(subscription, "a parameter for subscibers"); 

    // Verify 
    Assert.IsTrue(messageReceived); 
} 


public class EventAggregator 
{ 
    #region Singleton 
    static EventAggregator _eventAggregator = null; 
    private EventAggregator() { } 

    public static EventAggregator Instance 
    { 
     get 
     { 
      if (_eventAggregator == null) 
      { 
       _eventAggregator = new EventAggregator(); 
      } 

      return _eventAggregator; 
     } 
    } 
    #endregion 

    List<Observer> _observers = new List<Observer>(); 

    public void Register(string subscription, Action<object> response) 
    { 
     var observer = new Observer() { Subscription = subscription, Respond = response }; 
     _observers.Add(observer); 
    } 

    public void Publish(string subscription, object payload) 
    { 
     foreach (var observer in _observers) 
     { 
      if (observer.Subscription == subscription) 
      { 
       observer.Respond(payload); 
      } 
     } 
    } 
} 

public class Observer 
{ 
    public string Subscription { get; set; } 
    public Action<object> Respond {get; set; } 
} 
+0

С этой реализацией мы гарантировали утечку памяти, потому что вы не предоставляете возможности отменить/отменить регистрацию; поэтому все зарегистрированные ссылки на объекты будут постоянно храниться в вашем экземпляре EventAggregator, чтобы сборщик мусора очистил их. – dymanoid

+0

Вы правы. Для ясности я удалил метод Clear(). В центре моего ответа лежит исходный вопрос. Все остальные детали затмевают пример кода. Спасибо хоть. –

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

  • Нет связанных вопросов^_^