C# 从其他窗体访问函数

C# 从其他窗体访问函数,c#,winforms,C#,Winforms,我正在用c语言编写一个程序,它使用一个列表框作为其主要形式的选择方法。它具有可以编辑列表框中的项目的功能 我想从一个单独的专用表单编辑项目,因此我创建了一个新的表单实例,但每当我尝试访问原始表单的功能(我已公开)时,我都会遇到以下错误: 错误2非静态字段、方法或属性需要对象引用 我在互联网上看过很多次,但我看到的只是人们在谈论在我的函数中使用静态属性。然而,当我这样做的时候,我会在函数中的变量等上面出现更多的错误 这是Form1中的函数(我正在尝试引用) 下面是一个错误发生的代码片段(我在将代码

我正在用c语言编写一个程序,它使用一个列表框作为其主要形式的选择方法。它具有可以编辑列表框中的项目的功能

我想从一个单独的专用表单编辑项目,因此我创建了一个新的表单实例,但每当我尝试访问原始表单的功能(我已公开)时,我都会遇到以下错误: 错误2非静态字段、方法或属性需要对象引用

我在互联网上看过很多次,但我看到的只是人们在谈论在我的函数中使用静态属性。然而,当我这样做的时候,我会在函数中的变量等上面出现更多的错误

这是Form1中的函数(我正在尝试引用)

下面是一个错误发生的代码片段(我在将代码保存到文本文件时剪切了一些代码,但主要关注的是Form1.ReadFile(Form1.file)

private void按钮保存单击(对象发送者,事件参数e)
{
字符串[]temp=File.ReadAllLines(Form1.File);
字符串[]新文件;
if(itemNew==true)
{
newFile=新字符串[temp.Length+1];
}
其他的
{
newFile=新字符串[temp.Length];
}
对于(int i=0;i
我希望有足够的代码可以运行。我的程序相当长,所以我尽量让它尽可能简短直接。谢谢你耐心地对待我=]

我是一个编程新手,所以如果有什么样的灵魂能帮助我,你能让它尽可能简单吗


非常感谢=]

您正在对类型而不是对类型的实例调用方法。当方法未声明为静态时,您需要首先实例化包含这些方法的对象(使用new).

这可能是因为您试图从第二个窗口开始使用存在于第一个窗口中的函数,就像它们是静态的一样,但它们不是

您可以尝试通过以下方式解决此问题:

  • 在第二个表单中,使用第一个表单的类创建属性,如:

    class Form1 : Form
    {
        //this property will store reference to the first form
        public Form1 AssociatedFirstForm { get; set; }
        //...
    }
    
  • 然后在创建第二个表单的代码中,将第一个表单指定给此属性,如下所示(如果从第一个表单创建第二个表单):

或者类似这样(如果您从代码的另一部分创建两个表单):

  • 然后,在第二个表单中,您应该能够从第一个表单调用如下方法:

    ...
    var myResultFromAnotherWindow = this.AssociatedFirstForm.SampleMethodToCall();
    ...
    
我想你也应该多读一些关于使用和的书。它应该让你清楚地知道如何以及何时使用它们

更新

我写得还不够清楚,但是如果不需要的话,应该避免将expose方法或属性设置为public

如果您想在应用程序中创建良好的代码结构,并了解应该如何做到这一点,请查找一些关于面向对象编程的文章

一些示例链接:


了解事件机制也很有用:。

以下是您试图实现的基本想法。更高级的方法是使用委托/事件处理程序,但现在希望保持简单

表格一

 public Form1()
    {
        InitializeComponent();
    }

    List<string> _items = new List<string>();

    public void LoadListBoxWithItems()
    {
        for (int i = 0; i < 5; i++)
        {
            _items.Add(string.Format("My New Item {0}", i));
        }
        lbItems.DataSource = _items;
        lbItems.Refresh();
    }

    private void btnUpdate_Click(object sender, EventArgs e)
    {
            Form2 form2 = new Form2();
            form2.LoadValues(lbItems.SelectedItem.ToString(), this);
            form2.ShowDialog();
    }

    public string GetCurrentItem()
    {
        return lbItems.SelectedItem.ToString();
    }

    public void UpdateItem(string item, string newitem)
    {
        int index = _items.IndexOf(item);
        _items[index] = newitem;
        lbItems.Refresh();
    }

好的。现在把你的代码显示在你出错的地方。我们无法通过互联网阅读你的屏幕。请发布一些代码让人们看到你的想法。可能是重复的。所以,我知道这是为初学者准备的,但整个“保留对主窗体的引用并公开所有方法”是一种反模式(如果我见过的话)。更好的解决方案是使用事件向父窗体发出发生事件的信号,允许它根据需要更新其状态以作出响应。我只是无法按照当前编写的方式对此进行升级表决。我尝试了此操作,但现在我遇到了另一个错误。这次,错误2指定了该项在“Resources”参数中多次出现。重复项不受“Resources”支持参数。我将关联的类放在最顶部,就在公共部分类Form2:Form的上方。我不确定这是否是正确的位置,但它已消除了原始错误。非常感谢迄今为止的帮助=]@Ed S:我不会告诉您将所有方法公开,因为正如您已经说过的,这将违反面向对象的原则d编程概念。但是,如果一个方法(或属性)是窗体所做的特殊事情,它可以将其公开为公共,因此另一个窗体(即其父窗体)可以使用它(如从
OpenFileDialog
form读取
FileName
)。也许我应该写封信,不要在答案中暴露公众成员。@Graham Charlesby:看来你在使用资源(即resources.resx文件)保留您的一些资源。验证每个资源是否都有唯一的名称。老实说,我没有意识到这一点,我甚至不知道怎么做。我是否出了什么问题?=/为什么示例代码中有xml注释?尤其是它们没有完成。@Peri这是一种习惯。我的大多数代码都被其他人使用,我有一个cer这是我遵循的流程。1.编写方法-一旦我认为它完成了-我添加xml注释部分并折叠。2.针对代码/重构/等编写所有测试。一旦所有测试都通过了-我返回并填写注释/签入前需要的任何附加注释。
...
Form2 secondForm = new Form2();
secondForm.AssociatedFirstForm = this;
...
    ...
    Form1 firstForm = new Form1();
    Form2 secondForm = new Form2();
    secondForm.AssociatedFirstForm = firstForm;
    ...
...
var myResultFromAnotherWindow = this.AssociatedFirstForm.SampleMethodToCall();
...
 public Form1()
    {
        InitializeComponent();
    }

    List<string> _items = new List<string>();

    public void LoadListBoxWithItems()
    {
        for (int i = 0; i < 5; i++)
        {
            _items.Add(string.Format("My New Item {0}", i));
        }
        lbItems.DataSource = _items;
        lbItems.Refresh();
    }

    private void btnUpdate_Click(object sender, EventArgs e)
    {
            Form2 form2 = new Form2();
            form2.LoadValues(lbItems.SelectedItem.ToString(), this);
            form2.ShowDialog();
    }

    public string GetCurrentItem()
    {
        return lbItems.SelectedItem.ToString();
    }

    public void UpdateItem(string item, string newitem)
    {
        int index = _items.IndexOf(item);
        _items[index] = newitem;
        lbItems.Refresh();
    }
  public Form2()
    {
        InitializeComponent();
    }

    private string _originalvalue = null;
    private Form1 _form1;

    public void LoadValues(string item, Form1 form)
    {
        _originalvalue = item;
        _form1 = form;
    }


    private void btnSave_Click(object sender, EventArgs e)
    {
        // Do work to change value
        string newvalue = _originalvalue;
        _form1.UpdateItem(newvalue, _originalvalue);
    }