拦截.Show函数调用

时间:2013-11-16 18:10:54

标签: c# winforms c#-4.0

我正在开发一个应用程序,我希望在调用任何形式的.Show函数时执行自定义代码。基础是我有一个System.Windows.Form继承的类

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

这个类将在我的代码中的某个地方实例化,我将调用.Show方法来显示表单。

当我的应用程序显示一个新表单时,我想在其他窗口中创建一个新按钮,可以像任务栏一样理解。

有没有办法在不继承System.Windows.Form类的情况下执行此操作?

1 个答案:

答案 0 :(得分:2)

您可以订阅Shown - 活动。这样您就不必创建派生类。这是一个示例,在按下按钮时显示新表单。当显示创建的表单时,事件将显示一个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);
    }
}