C# 仅使用用户控件时,如何在主窗体面板中显示用户控件?

C# 仅使用用户控件时,如何在主窗体面板中显示用户控件?,c#,winforms,C#,Winforms,@Mark,是的,长官,我在usercontrol中创建了一个事件。 这是我的密码: 用户控制 namespace Purchase_Order { public partial class Static : UserControl { public event EventHandler ClassificationClicked; public Static() { InitializeComponent(

@Mark,是的,长官,我在usercontrol中创建了一个事件。 这是我的密码:

用户控制

namespace Purchase_Order
{
    public partial class Static : UserControl
    {
        public event EventHandler ClassificationClicked;
        public Static()
        {
            InitializeComponent();
        }

        private void btnClassification_Click(object sender, EventArgs e)
        {
            ClassificationClicked(sender, e);
        }
    }
}
MAINFORM

public partial class formMain : Form
{

    public formMain()
    {
        InitializeComponent();
        Static.ClassificationClicked += new EventHandler(Static_ClassificationClicked); 
    }

    private void formMain_Load(object sender, EventArgs e)
    {
        Static control = new Static();
        panelSide.Controls.Clear();
        panelSide.Controls.Add(control);   
    }

    void  Static_ClassificationClicked(object sender, EventArgs e)
    {
        classification control = new classification();
        panelMain.Controls.Clear();
        panelMain.Controls.Add(control);
    }

}

下面是错误->Static.ClassificationClicked+=neweventhandler(Static\u ClassificationClicked)

我假设
btnClassification\u Click
static
用户控件上的一种方法,它位于
formMain
的实例上

您的问题是,在
btnClassification\u单击
方法时,您创建了
formMain
类的新实例,而不是访问您的
static
用户控件所在的实例。看起来您已经在
formMain
类中公开了
mainPanel
,因此您只需要找到
formMain
类的正确实例,将用户控件添加到该类中。为此,请将此方法放在
静态
用户控件中:

private Form GetParentForm()
{
    Control current = this.Parent;
    while (current != null)
    {
        Form form = current as Form;
        if (form != null)
        {
            return form;
        }

        current = current.Parent;
    }

    return null;
}
然后从事件处理程序调用此方法:

private void btnClassification_Click(object sender, EventArgs e)
{
    classification control = new classification();
    formMain main = (formMain)this.GetParentForm();
    main.panelMain.Controls.Clear();
    main.panelMain.Controls.Add(control);
}

我个人会在你的UserControl上创建一个事件,并在你的MainForm中订阅它。在我看来,UserControl了解父窗体是不合适的。大概是这样的:

将事件添加到用户控件:

public partial class UserControl1 : UserControl
{
    public event EventHandler ClassificationClicked;
    public UserControl1()
    {
        InitializeComponent();
    }

    private void btnClassification_Click(object sender, EventArgs e)
    {
        ClassificationClicked(sender, e);
    }
}
在主表单中订阅它

public partial class Form1 : Form
{
    public Form1()
    {
        InitializeComponent();
        userControl11.ClassificationClicked += new EventHandler(userControl11_ClassificationClicked);
    }

    void userControl11_ClassificationClicked(object sender, EventArgs e)
    {
        classification control = new classification();
        panelMain.Controls.Clear();
        panelMain.Controls.Add(control);

    }
}

基于评论流进行编辑。我还要确保你的Usercontrols有唯一的名称,而不仅仅是control,这样你就可以区分它们了

public partial class formMain : Form
{
    Static staticControl;
    Classification classificationControl;

    public formMain()
    {
        InitializeComponent();
        staticControl= new Static();
        panelSide.Controls.Clear();
        panelSide.Controls.Add(staticControl);
        staticControl.ClassificationClicked += new EventHandler(Static_ClassificationClicked); 
    }

    void  Static_ClassificationClicked(object sender, EventArgs e)
    {
        classificationControl = new classification();
        panelMain.Controls.Clear();
        panelMain.Controls.Add(classificationControl);
    }

}
答案是最好的,但是我想补充一点,您不应该直接引发事件,而是首先检查是否有订阅者,然后引发事件。如果还没有人订阅该事件,这将停止空引用异常

public partial class UserControl1 : UserControl
{
    public event EventHandler ClassificationClicked;
    public UserControl1()
    {
        InitializeComponent();
    }

    private void btnClassification_Click(object sender, EventArgs e)
    {
        RaiseClassifactionClicked();
    }

    private RaiseClassifactionClicked()
    {
        var tmp = ClassificationClicked; //This is added for thread safty
        if(tmp != null) //check to see if there are subscribers, if there are tmp will not be null
           tmp(this, EventArgs.Empty); //You don't need to pass along the sender and e, make your own here.
    }
}

有关线程安全技巧的详细信息,请阅读

Yes btnClassification\u单击是一种方法,但它位于用户控件“static”上。是否在用户控件中创建了事件?再看一下我的示例中的usercontrol示例answer@Mark,是的,先生,我在usercontrol中创建了一个事件。这是我的代码:>名称空间购买顺序{public partial class Static:UserControl{public event EventHandler ClassificationClicked;public Static(){InitializeComponent();}private void btnClassification\u Click(对象发送方,事件参数e){ClassificationClicked(发件人,e);}}您的主窗体的命名空间是什么,我没有看到任何错误。在尝试添加eventhandler之前,请先尝试编译您的UserControl,然后查看事件是否存在。@Mark,我的主窗体的命名空间是Purchase\u Order。我尝试了您所说的,我对行->Static.ClassificationClicked+=new eventhandler进行了注释(Static_ClassificationClicked);但在我单击按钮分类(btnClassification)后,它返回了一个错误(对象引用未设置为对象的实例)。为什么会这样?在FormMain中添加
control.ClassificationClicked+=new EventHandler(Static_ClassificationClicked);
\u加载EventHandler。