简体   繁体   English

动态创建的用户控件,可从主窗体中检测按钮单击

[英]Dynamically created User Control detecting button click from main Form

I have been trying to figure this out for the better part of two days and have searched everywhere to find a solution, so if this is easily answered I apologize up front. 我一直试图在两天的时间里弄清楚这一点,并且在所有地方都进行了搜索以找到解决方案,因此,如果这很容易得到解答,我将向您道歉。 Also, I am fairly new to c# and programming in general. 另外,我对C#和一般编程还是比较陌生。

I have a wherein one button creates a new . 我有一个其中一个按钮创建了一个新的 This user control has a listview (for now, at some point I'm probably going to change this to a datagridview) that is updated with information from an Access database. 此用户控件具有一个列表视图(目前,在某个时候,我可能会将其更改为datagridview),该列表视图已使用Access数据库中的信息进行了更新。 When another button (Save) on the Form is clicked, information is added to the database. 单击窗体上的另一个按钮(保存)时,信息将添加到数据库中。 I would like for my UserControl to detect when the Save button is clicked and update the listview. 我希望UserControl检测何时单击“保存”按钮并更新列表视图。

Below is a sample from my code, trimmed down to what I hope are the important bits. 下面是我的代码示例,并整理为我希望的重要部分。

Form stuff. 表格的东西。

public partial class Form1 : Form
{
    public event EventHandler saveClick;

    public Form1()
    {
        InitializeComponent();
    }

    public void buttonSave_Click(object sender, EventArgs e)
    {
        //Stuff happens here that saves all input to the database
        if (this.saveClick != null)
            this.saveClick(this, e);            
    }

    //Creates the UserControl TodayCallHistory as tch and expands Form1 window to accomodate the new control
    private void butListShow_Click(object sender, EventArgs e)
    {
        if (!expanded)
        {
            expanded = true;
            butListShow.Text = "\u25C0";
            TodayCallHistory tch = new TodayCallHistory();
            tch.Name = "tch";
            tch.SetParentForm(this); //This was added per the answer below
            List<int> pos = new List<int>();
            foreach (Control x in this.Controls)
            {
                int right = x.Right;
                pos.Add(right);
            }
            tch.Location = new System.Drawing.Point(pos.Max() + 10, 10);
            formWidth = this.Width;
            this.Width = this.Width + tch.Width + 10;
            this.Controls.Add(tch);
        }
        else
        {
            expanded = false;
            butListShow.Text = "\u25B6";
            foreach (Control x in this.Controls)
            {
                if (x.Name == "tch")
                    this.Controls.Remove(x);
            }
            this.Width = formWidth;
        }
    }
}

UserControl stuff. UserControl的东西。

public partial class TodayCallHistory : UserControl
{
    private Form1 frm = new Form1();

    public TodayCallHistory()
    {
        InitializeComponent();
        //frm.saveClick += new EventHandler(saveWasClicked); Removed based on answer below
    }

    //This following part was added per the marked answer below
    public void SetParentForm(Form1 parent)
    {
        frm = parent;
        frm.saveClick += new EventHandler(saveWasClicked);
    }

    private void saveWasClicked(object sender, EventArgs e)
    {
        refreshList();
    }

    private void refreshList()
    {
        //Sends query to database and then populates a listview with this information
    }
}

When the Save button is clicked on the Form, nothing happens on the UserControl. 在窗体上单击保存按钮时,UserControl上没有任何反应。 Just a big ole pile of nothing. 只是一大堆什么都没有。 If anyone can tell me what I'm doing wrong or a better way to approach this, I would be extremely grateful! 如果有人能告诉我我做错了什么或解决这个问题的更好方法,我将万分感谢! I can also post more of my code if I'm not sharing enough. 如果共享不足,我还可以发布更多代码。

EDIT 1: I should also mention that this is a WinForm, written in c# using Visual Studio Express 2015 for Windows Desktop. 编辑1:我还应该提到这是WinForm,使用Visual Studio Express 2015 for Windows Desktop用c#编写。

EDIT 2: Added my code for creating the UserControl when a button is clicked on Form1. 编辑2:添加了用于在Form1上单击按钮时创建UserControl的代码。 The same button also removes the control. 同样的按钮也可以删除控件。 Basically I wanted to have an "expand window" (I have no idea what the actual term should be) feature as part of my Form1. 基本上,我希望在Form1中有一个“扩展窗口”(我不知道实际的术语是什么)功能。

EDIT 3: Using Harrison Paine's (not sure how to tag a username) suggestion below, I added the SetParentForm method to the UserControl. 编辑3:使用下面的哈里森·潘恩(不确定如何标记用户名)的建议,我将SetParentForm方法添加到UserControl。 Since my UserControl isn't created until the button click on Form1, I had to add the SetParentForm on Form1 after it was created. 因为直到单击按钮Form1才创建我的UserControl,所以我必须在创建Form1后在Set1上添加SetParentForm。

Right after 之后

tch.Name = "tch";

I added 我补充道

tch.SetParentForm(this);

EDIT 4: So as to avoid creating a new Form1, I made the following changes. 编辑4:为了避免创建新的Form1,我进行了以下更改。

Form1 Form1中

public static event EventHandler saveClick; //Added static modifier 

public void buttonSave_Click(object sender, EventArgs e)
{
    //Stuff happens here that saves all input to the database
    if (Form1.saveClick != null)
        Form1.saveClick(this, e); //Changed this.saveClick to Form1.saveClick 
}

private void butListShow_Click(object sender, EventArgs e)
{
tch.Parent = this; //All the other stuff from above, plus this now
}

I changed this.saveClick to Form1.saveClick since it is has the static modifier (I mostly guessed I had to do this and am still working on understanding exactly what 'static' does hah) 我将this.saveClick更改为Form1.saveClick因为它具有static修饰符(我大多猜想我必须这样做,并且仍在努力确切地了解“ static”的作用)

UserControl 用户控件

    public TodayCallHistory()
    {
        Form1.saveClick += new EventHandler(saveWasClicked);
        InitializeComponent();
    }

I removed the Form1 frm = new Form1(); 我删除了Form1 frm = new Form1(); as well as the entire SetParentForm method. 以及整个SetParentForm方法。

For those wondering why I didn't just have the UserControl created and always there, with just a .Visible set to True or False , I determined after much reading that the "better practice" is to create and destroy controls as you need them, especially if you have a lot of them on a form. 对于那些想知道为什么我不只是创建UserControl并始终将其设置为.Visible设置为TrueFalse ,经过大量阅读后,我确定“更好的做法”是根据需要创建和销毁控件,特别是如果您在表单上有很多。 If I'm completely off-base/insane on this, please let me know so I can take the easy way out :) 如果我对此完全不满意,请告诉我,这样我可以采取简单的方法:)

It looks like your TodayCallHistory is creating its own Form1 and listening to an event on that object. 您的TodayCallHistory正在创建自己的Form1并在该对象上监听事件。

You need to pass in the actual Form1 that has the user control and then register the event handler on that object. 您需要传入具有用户控件的实际Form1 ,然后在该对象上注册事件处理程序。

Something like this: 像这样的东西:

In TodayCallHistory.cs : TodayCallHistory.cs

public void SetParentForm(Form1 parent)
{
    frm = parent;
    frm.SaveClick += new EventHandler(saveWasClicked);
}

In Form1.cs : Form1.cs

public Form1
{
    InitializeComponent();
    this.myTodayCallHistory.SetParentForm(this);
}

The issue stems from the following: 该问题源于以下方面:

public partial class TodayCallHistory : UserControl
{
    private Form1 frm = new Form1();

The Form1 created here is an entirely different object than the "original" one, whose save button you are clicking. 此处创建的Form1是与“原始”对象完全不同的对象,“原始”对象正在单击其保存按钮。 Instead of creating a brand new object, you need to pass the original one in somehow. 无需创建全新的对象,您需要以某种方式传递原始对象。 The SetParentForm() method is just one way to do this. SetParentForm()方法只是执行此操作的一种方法。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM