如何避免子窗体按钮单击事件以调用父窗体处理程序

时间:2014-11-07 21:56:16

标签: c# .net windows-mobile-6.5

我正在使用Windows Mobile CE。我有以下问题。

我有一个父表单BookForm,它在书籍编号,作者等表格中显示书籍信息。我在屏幕上有一个按钮,显示"确定",它充当后退按钮。

我有一个子窗体PaidBookForm,它在相同的UI布局中显示相同的数据。我在屏幕上有一个按钮btnSubmit,上面写着" Buy",它将用户带到另一个用户可以购买书籍的屏幕。

public partial class PaidBookForm : BookForm 
{
}

我将事件处理程序分配给父表单中的btnSubmit

this.btnSubmit.Click += new System.EventHandler(this.btnBack_Click);  

我将事件处理程序分配给子窗体中的btnSubmit

this.btnSubmit.Click += new System.EventHandler(this.btnBuy_Click);  

问题是:

when Buy is clicked in child form, btnBack_Click is called first and btnBuy_Click is called. How do I avoid btnBack_Click to be called ?

2 个答案:

答案 0 :(得分:1)

由于PaidBookForm继承自BookForm,因此它具有与其父级具有的所有相同的代码和事件处理。这包括您在基类中定义的事件订阅。因此,在您的子表单中,有2个事件从基类btnSubmit.Click订阅btnBack_Click - BookForm,从子类btnBuy_Click订阅PaidBookForm

有几种方法可以解决这个问题。一种选择是在连接子类事件之前修改子表单代码以取消订阅基类事件,如下所示(SLOPPY CODING,NOT WOMOMENDED):

this.btnSubmit.Click -= new System.EventHandler(this.btnBack_Click);
this.btnSubmit.Click += new System.EventHandler(this.btnBuy_Click);

更好的选择是重新评估您对继承的使用。听起来这两种形式有不同的用途,但您使用的是继承,因为它们具有相似的UI布局。这违反了Liskov substitution principle(在使用UI继承时很常见)。

相反,请考虑创建包含所有常用UI元素的UserControl,然后将该用户控件添加到BookFormPaidBookForm类中。然后你的两个表格将共享具有共同元素的相同BookInformationControl(或任何你称之为),但它们的事件处理将完全分开。

答案 1 :(得分:0)

首先要记住的是,您的“子表单”也是您的“父表单”。它们不是两个不同的对象。子表单是父表单的一个实例,具有其他功能。

在这种情况下,似乎多态可能是要走的路。而不是当前的事件处理程序订阅,请执行以下操作:

class BookForm : Form
{
    protected virtual void SubscribeButton()
    {
        this.btnSubmit.Click += new System.EventHandler(this.btnBack_Click);
    }

    public BookForm()
    {
        InitializeComponent();
        SubscribeButton();
    }
}

class PaidBookForm : Form
{
    protected override void SubscribeButton()
    {
        this.btnSubmit.Click += new System.EventHandler(this.btnBuy_Click);
    }
}

如果这不符合您的需求,您真的需要发布一个好的代码示例。