2013-11-16 3 views
0

Я разрабатываю приложение, в котором я хочу выполнить собственный код, когда вызывается функция .Show любой формы. Основы есть у меня есть System.Windows.Form унаследованного классПерехват .После вызова функции

class Test : System.Windows.Forms 
{ 
    ... do some stuff 
} 

Этот класс будет инстанцированным где-то в моем коде, и я буду вызывать метод .Show для того, чтобы показать форму.

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

Есть ли способ сделать это без наследования класса System.Windows.Form?

+0

Вы можете использовать общий метод 'show' вашу форму, в этом общем методе сделайте свою задачу. –

+0

Легкий способ - наследовать от 'System.Windows.Form' и использовать производный тип вместо' Syst em.Windows.Form'. Трудный путь - это IL Weaving, использующий любую библиотеку, которая поддерживает его как [PostSharp] (http://www.postsharp.net/aop.net/msil-injection), но это довольно кривая обучения. – Tilak

+0

@ Тилак Как это помогает? 'Show' не является виртуальным методом. –

ответ

2

Вы можете подписаться на Shown -Event. Таким образом, вам необязательно создавать производный класс. Вот пример, который отображает новую форму при нажатии кнопки. Когда отображается созданная форма, событие отображает MessageBox (это та часть, в которую войдет логика создания вашей кнопки). Я также подписался на событие FormClosed, где вы хотите удалить кнопку с панели задач.

private void button1_Click(object sender, EventArgs e) 
{ 
    Form popup = new Form(); 
    popup.Shown += popup_Shown; 
    popup.FormClosed += popup_FormClosed; 

    popup.Show(); 
} 

void popup_FormClosed(object sender, FormClosedEventArgs e) 
{ 
    //TODO:Remove button from taskbar 
    MessageBox.Show("Popup closed."); 
} 

void popup_Shown(object sender, EventArgs e) 
{ 
    //TODO:Add button to taskbar 
    MessageBox.Show("Popup shown."); 
} 

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

MainForm.cs

public Form1() 
    { 
     InitializeComponent(); 

     PopupManager.PopupClosed += PopupManager_PopupClosed; 
     PopupManager.PopupOpened += PopupManager_PopupOpened; 
    } 

    void PopupManager_PopupOpened(object sender, PopupStateChangedEventArgs e) 
    { 
     MessageBox.Show(e.Popup.Caption + " was opened"); 
    } 

    void PopupManager_PopupClosed(object sender, PopupStateChangedEventArgs e) 
    { 
     MessageBox.Show(e.Popup.Caption + " was closed"); 
    } 

    private void button1_Click(object sender, EventArgs e) 
    { 
     PopupForm popup = new PopupForm("TestPopup"); 
     popup.Show(); 
    } 

PopupManager.cs

public static class PopupManager 
{ 
    static PopupManager() 
    { 
     openForms = new List<PopupForm>(); 
    } 

    private static List<PopupForm> openForms; 

    public static event EventHandler<PopupStateChangedEventArgs> PopupOpened; 
    public static event EventHandler<PopupStateChangedEventArgs> PopupClosed; 

    internal static void AddPopup(PopupForm popup) 
    { 
     if (openForms.Contains(popup)) 
      throw new ArgumentException("Popup already open", "popup"); 

     openForms.Add(popup); 

     if (PopupOpened != null) 
      PopupOpened(null, new PopupStateChangedEventArgs() { Popup = popup }); 
    } 

    internal static void RemovePopup(PopupForm popup) 
    { 
     if (!openForms.Contains(popup)) 
      throw new ArgumentException("Popup not open", "popup"); 

     openForms.Remove(popup); 

     if (PopupClosed != null) 
      PopupClosed(null, new PopupStateChangedEventArgs() { Popup = popup }); 
    } 
} 

public class PopupStateChangedEventArgs : EventArgs 
{ 
    public PopupForm Popup {get; set;} 
} 

PopupForm.cs

public class PopupForm : Form 
{ 
    public string Caption { get; private set; } 


    public PopupForm(string caption) 
    { 
     this.Caption = caption; 
    } 

    protected override void OnShown(EventArgs e) 
    { 
     base.OnShown(e); 
     PopupManager.AddPopup(this); 
    } 

    protected override void OnClosed(EventArgs e) 
    { 
     base.OnClosed(e); 
     PopupManager.RemovePopup(this); 
    } 
} 
+0

Спасибо за ответ ChrisK, но суть этого решения заключается в том, что я должен подписывать эти события вручную, когда создаю экземпляр формы. То, что я ищу, - это способ сделать это без изменения кода, который создает экземпляр формы вообще. – mmatachana

+0

Ну, порожденная форма должна иметь доступ к TaskBar в этом случае. Вы можете создать синглтон, содержащий информацию обо всех всплывающих подсказках. Затем полученный PopupForm войдет в этот синглтон. Но основной форме все равно нужно будет подписаться на обновления этого синглтона, хотя это будет только в одном месте. – ChrisK

+0

+1. @mmatachana - здесь используется код рефакторинга для централизации создания объектов.Если ваш код для создания объектов будет в одном месте, вам не составит труда добавить слушателей для всех новых форм. Основная форма, предложенная Хансом Пассантом (создайте метод, который завершает создание/показ формы), но вы можете пройти весь путь и использовать некоторую среду для инъекций зависимостей. Отъезд (Factory) [http://en.wikipedia.org/wiki/Factory_ (design_pattern)] и (шаблон фабричного метода) [http://en.wikipedia.org/wiki/Factory_method_pattern] для получения более подробной информации –

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