正在学写一个应用程序,其中要在不同窗体之间传递数据,也在网上找了一些资料,总是觉得很麻烦,最简单的方法好象就是专门写一个类,在其中建立静态共有变量,然后利用这个类,来实现不同窗体之间的数据传递。但这样有一个问题,就是这个类需要多少个静态共有变量,在写程序的一开始是定不下来的,而且以后如果要新添加某些数据的传递,还要去修改这个“全局”的类。
请问各位老鸟,有没有更好,或是更简便的方法,来实现窗体之间的数据通信。

解决方案 »

  1.   

    比如说在主窗体中new了一个类,而在子窗体中需要对这个类的实例进行操作。那么怎么把这个类的实例从主窗体传递到子窗体中,而在子窗体中对这个实例进行操作后,又怎么再传回到主窗体中。
      

  2.   

    MDI窗体,公共变量设置在父窗口就行了
      

  3.   

    目前想到的办法是,在主窗体中将要传出去的类,在实例化的时候,前面加上public。但不知道这样是否符合编程规范。而且,这对自己定义的类有用,而对于主窗体上面的控件,又该怎么办呢?
      

  4.   


    namespace NewOPCClient
    {
        public partial class Main : Form
        {
            public Main()
            {
                InitializeComponent();
            }
            public  myComOPC tmpComOPC = new myComOPC();//这里用public来实现,感觉不是这么回事。这里的myComOPC是自己写的类。我现在想在另外一个窗体里对tmpComOPC这个实例进行操作,难道只能用加public的方法吗?有没有更简单,或是更符合编程良好习惯的办法呢?
      

  5.   

    不行,我的这个办法也不行。系统提示:
    错误 1
    可访问性不一致: 字段类型“NewOPCClient.myComOPC”比字段“NewOPCClient.Main.tmpComOPC”的可访问性低
    E:\最新工业自动化\C#项目\NewOPCClient\NewOPCClient\Main.cs 22 26 NewOPCClient
      

  6.   

    提高myComOPC的可访问性,设置为PUBLIC
      

  7.   

    是在myComOPC这个类的定义前加Public吗?我试了,可以。但这是怎么回事?
      

  8.   

    而且还有个问题,将来我可能多次实例化myComOPC这个类,因为我要建立起好几个OPC连接,如果我现在用了public在myComOPC这个类的定义前面,那么我对这个类的某一个实例的操作,会不会影响该类的其他实例?
      

  9.   

    你的意思是说,如果我把myComOPC这个类设置为public,该类的不同实例是不会互相影响的,对吗?
    那这个public加与不加,有什么区别呢?
      

  10.   

    声明一个类的访问权限,是在定义这个类的时候做的事情,所以你要在定义这个类的时候,在类名前面放一个Public修饰符还有你说的那个疑惑,不会影响在其他实例,放心使用
      

  11.   

    第二个窗体你总得初始化吧!在第二个窗体构造函数中你添加一个参数咯!该参数用来接收你从Form1传过来的值,这样该值就能在两个窗体之间共享了!
    不知道可不可以解决你说的这个问题?呵呵……
      

  12.   

    呵呵,谢谢。
    刚才试了一下,又发现新问题。在子窗体,对主窗体的myComOPC的实例tmpComOPC进行了连接后,再退回主窗体,发现连接断掉了。是不是C#的什么垃圾回收机制起作用了,自动把连接切断了,有没有什么办法解决呢?这其实还是通信问题吧,把信息(变量,类的实例)传递出去,再接受回来。
      

  13.   

    是数据的话你可以还可以建立一个临时的XML配置文件用来共享数据,或者把数据保存到数据库;这样的话无论哪个窗体调用你只需要对配置文件或者数据库中的对应信息进行改动就可以了!
      

  14.   

    再问一下啊:
    在子窗体,对主窗体的myComOPC的实例tmpComOPC进行了连接后,再退回主窗体,发现连接断掉了。是不是C#的什么垃圾回收机制起作用了,自动把连接切断了,有没有什么办法解决呢?这其实还是通信问题吧,把信息(变量,类的实例)传递出去,再接受回来。
      

  15.   

    //try:
    public  static myComOPC tmpComOPC = new myComOPC();//in SubForm:
    Main.tmpComPC=shit;
    ...
      

  16.   

    在一个类里定义一个hashtable结构。
    把你需要共享的类加入到hashtable中,在其他的窗口中使用就好了。
    例如:
    public class abc
    {
        public static HashTable hashdata = new HashTable();
        
        //Do something....
    }public class FrmMain: Form
    {
        public FrmMain()
        {
            abc.hashdata("FrmMain", this);
        }
       
        public void AFunction()
        {
        }
    }public class FrmTemp: Form
    {
        public FrmTemp()
        {
            FrmMain FrmMainA = null;
            foreach(DictionayEntry de in hashdata)
            {
                if(de.Key.ToString() == "FrmMain")
                {
                    FrmMainA = (Form)de.Value;
                    break;
                }
            }
            
            FrmMainA.AFunction();
            
        }
    }
      

  17.   

    学习了!
    我一般是改子窗体的构造函数,在父窗体调用的时候
    new form(this);
    这样就可用父窗体的变量了
    不知是不是答非所问……
      

  18.   

    能不能说得详细一点啊,比如给个简单的代码,谢谢了。看了书,还是不直观。说实话,以前用delphi和vb的,太不习惯。
      

  19.   

    33楼的应该可以吧
    对象一样可以传
    this是主窗口的指针
    在子窗口中可以用这个this调用任何主窗口的public对象
      

  20.   


    //1、用静态变量,就是LZ说的
    //2、在主窗体声明一个属性,然后在打开的窗体就可以访问了//主窗体MainForm
    private string username;
    public string UserName
    {
        get{return "aaaaaaaa";}
        set{username=value;}
    }
    //打开的窗体Form1
    ((MainForm)this.Own).UserName="dgd";
    //3、构造函数
    //打开的窗体Form1,添加一个构造函数或者直接修改也可以
    private string username;
    public Form1(string username):Form1()
    {
       this.username=username;
    }//4、委托事件
    //比如在打开的窗体点击按钮修改主窗体的TextBox
    //先在打开的窗体声明委托和事件
    public delegate void aa();//参数自己定义//然后在类里面声明事件public event aa aaEvent;protected virtual void OnaaEvent()
    {
       if(aaEvent!=null)
       {
          aaEvent();
       }
    }//再次在点击按钮中引发事件
    private void Buttom1_Click(object sender,EventArgs e)
    {  
        //其他代码
        OnaaEvent();
    }
    //最后在主窗体注册事件Form1 f1=new Form1();
    f1.aaEvent+=delegate(){MessageBox.Show("LZ给我分吧")}
      

  21.   

    接你这个前提
    通常做法不需要静态的数据了,而是一个普通的类就可以了
    然后在新的窗体中通过构造函数参数传递该类(在VC++里叫 Document)
    例如:MainForm
    {
       ///这个类存放相关信息
       Doc MainFormDoc;
    }NForm
    {
      Doc NFormDoc;
      NForm(Doc pDoc)
      {
         NFormDoc=pDoc;
      }
    }这样通过修改pDoc的数据就可以实现全局数据更新,如果要使用主窗体,可以在定义Doc时包含:Doc
    {
      MainForm mMainForm;
    }这样所有的窗体和数据都可以实现交互了.
      

  22.   

    把UI与逻辑分离也是比较好的做法MVC,MVP不正是这样的嘛
      

  23.   

    如果要松耦合的话,可以用socket通讯。
      

  24.   

    建议用socket实现 很方便!