简体   繁体   English

如何从c#中的另一个winform运行方法?

[英]How can I run a method from a another winform in c#?

I have an "addEngine" method in a form called Products and i have an "Add New Engine" button. 我有一个名为Products的形式的“addEngine”方法,我有一个“添加新引擎”按钮。

public partial class Products : Form
{ 
    public void addEngine(short EngineID, string NumberPerUnit, string Manufacturer, string ModelSeriesYear)
    {
        try  
        {
            productCurrentRow = ((DataRowView) productEngineBindingSource.Current).Row;
            int productID = (int) productCurrentRow["ProductID"];

            var engines = from engine in productDataset.ProductEngine
                          where engine.ProductID == productID
                          select engine;

            foreach (var engine in engines)
            {
                if (engine.EngineID == EngineID)
                {
                    UC.alertError("Record already exists!");
                    return;
                }
            }

            var newEngineRow = productDataset.ProductEngine.NewProductEngineRow();
            newEngineRow.EngineID = EngineID;
            newEngineRow.ProductID = productID;
            newEngineRow.NumberPerUnit = NumberPerUnit;
            newEngineRow.Manufacturer = Manufacturer;
            newEngineRow.ModelSeriesYear = ModelSeriesYear;

            productDataset.ProductEngine.AddProductEngineRow(newEngineRow);
        }
        catch (Exception ex)
        {
            MessageBox.Show(ex.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
        }
    }

    private void btnAddNewEngine_Clicked(object sender, EventArgs e)
    {
        EngineFilter eginfilter = new EngineFilter();
        eginfilter.ShowDialog();
    }
}

When the buttion is clicked there is another form called "EngineFilter", which loads a list Engines. 单击按钮时,会有另一个名为“EngineFilter”的表单,它会加载列表Engines。 After user selects an item from the list and clicks "Select" buttion on the form, the information of the item is inserted a list (ProductEngine datatable) through the "addEngine" method on the "Product" form. 用户从列表中选择一个项目并单击表单上的“选择”按钮后,该项目的信息将通过“产品”表单上的“addEngine”方法插入一个列表(ProductEngine datatable)。 The problem is that i cannot pass the parameters between the two forms(classes) 问题是我无法在两个表单(类)之间传递参数

public partial class EngineFilter : Form
{
    public delegate void addEnineDelegate(short EngineID, string NumberPerUnit, string Manufacturer, string ModelSeriesYear);

    private void btnSelect_Click(object sender, EventArgs e)
    {
        Products product = new Products();                
        DataRow row = ((DataRowView) engineFilterBindingSource.Current).Row;
        addEnineDelegate mydelegate = new addEnineDelegate(product.addEngineMethod);

        mydelegate((short)row[2], "1", row[0].ToString(), row[1].ToString());
        this.Close();
    }
}

I've tried to use a delegate but there is a "Object reference not set to an instance of an object" error. 我试图使用委托,但有一个“对象引用没有设置为对象的实例”错误。 Is there anybody can give me a good practice to handle this? 有没有人可以给我一个好的做法来处理这个问题?

I aggree with Sam Holder, but if you want this code to work as it is right now, I would use events. 我与Sam Holder签约,但是如果你想让这段代码正常工作,我会使用事件。

Create your event in the EngineFilter 在EngineFilter中创建您的活动

Public event EventHandler<EngineFilterEventArgs> EngineFilterSelected;

Now second step is to create the EngineFilterEventArgs class and put every parameter you want in the eventargs. 现在第二步是创建EngineFilterEventArgs类并将所需的每个参数放在eventargs中。 Now I have just added an ID 现在我刚刚添加了一个ID

Public class EngineFilterEventArgs : EventArgs
{
    Public int Id {get; set;}
    Public EngineFilterEventArgs(int id)
    {
        Id = id;
    }
}

Third step is to fire the event. 第三步是开火活动。 Note that 1 is selectedId 注意1是selectedId

If(EngineFilterSelected != null)
     EngineFilterSelected(this, new EngineFilterEventArgs(1));

Now make sure that the other form is listening to the event. 现在确保另一个表单正在监听该事件。

    private void btnAddNewEngine_Clicked(object sender, EventArgs e)
    {
        EngineFilter enginFilter = new EngineFilter();
        engineFilter.EngineFilterSelected += handler;
        engineFilter.ShowDialog();
    }

Final step is to add your eventhandler 最后一步是添加你的事件处理程序

Protected void handler(object sender, EngineFilterEventArgs e)
{
    //TODO Handle your event
    Int selectedId = e.Id;
}

You could pass a reference to the form which contains the addEngine method to the form which you want to call this method from, and that would work, but is not a particularly great solution. 您可以将包含addEngine方法的表单的引用传递给您要调用此方法的表单,这样可以使用,但这不是一个特别好的解决方案。

Better would be to have a class which exposes this method, then pass the instance of this class to both forms for them to use. 更好的方法是有一个暴露这个方法的类,然后将这个类的实例传递给两个表单供他们使用。 This has better separation of concerns. 这有更好的关注点分离。 Really your form should not be responsible for updating the repository, what it should do is collect the user input and pass it to the class responsible for doing the update. 实际上,您的表单不应该负责更新存储库,它应该做的是收集用户输入并将其传递给负责执行更新的类。

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

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