none
表單互通一問? RRS feed

  • 問題

  • 我看了這篇文章http://www.dotblogs.com.tw/larrynung/archive/2009/03/24/7669.aspx的表單互通,也練習了一遍且有作用的,

    但是我把他改成關閉後Form2也能將資料設定Form1,但是確有錯誤,說是疑是無限迴圈? 為什麼呢? 還是說要達到這種結果不能用這種寫法?


    以下是程式

    Form1:

    namespace F1
    {
        public partial class Form1 : Form
        {
            Form2 f2 = new Form2();  //執行F2這行會出錯
            public Form1()
            {
                InitializeComponent();
               
            }

            private void button2_Click(object sender, EventArgs e)
            {           
                f2.numericUpDown1.Value = this.numericUpDown1.Value;
            }

            private void button1_Click(object sender, EventArgs e)
            {
                f2.ShowDialog();
            }  
        }
    }



    Form2:

    namespace F2
    {
    public partial class Form2 : Form
        {
            Form1 f1 = new Form1(); //執行F1這行會出錯
            public Form2()
            {
                InitializeComponent();
            }

            private void Form2_FormClosed(object sender, FormClosedEventArgs e)
            {
              
                f1.numericUpDown1.Value = this.numericUpDown1.Value;
            }
        }

    }

    2009年8月11日 下午 03:26

解答

  • Hi,

    你的問題點跟關不關掉無關
    程式運行就會發生了
    這搞不懂的話就是你對變數初始器沒有認知
    以你的程式來看
    Form1實體建立時會產生Form2 (因為你有加Form2 f2 = new Form2();)
    而Form2被建立後Form1又會建立 (因為Form1 f1 = new Form1();)
    所以你的程式變成
    New Form1=>New Form2=>New Form1=>New Form2....

    http://www.dotblogs.com.tw/larrynung/
    • 已標示為解答 Q楓仔Q 2009年8月13日 上午 09:11
    2009年8月12日 上午 03:37
  • 抄Code就是抄Code.沒什麼大不了的.寫十幾年的老程設師也在抄Code.包含我.
    程式架構要規劃也不是那麼簡單.需要花很多年時間.
    你最先的寫法,那個問題叫遞回參照.A->B,B又參照到A.我不知Form為什麼不會出現錯.如果你寫DLL專案.二支Class互相參照編譯時就錯了.

    • 已標示為解答 Q楓仔Q 2009年8月13日 上午 09:11
    2009年8月12日 上午 03:38
  •    我知道他會new新的, 我是疑問我關掉Form2讓值寫回Form1,為什麼會有無限迴圈,我是因為這點納悶才問的

     
          因為你寫在全域中啊. 產生一個Form的執行個體, 並不代表它一定要Show出來才叫產生,你只要New了這個執行個體就出現了.然後你又 1 產生2 , 2產生1 ......., 所以就會形成一個沒完沒了的迴圈
           還有一個重點: 你每次產生的執行個體雖然是參考同一個Class , 但是它是不同的執行個體.
         

    請關心自己的問題,不要問了就放空;這是對別人與自己的尊重
    • 已標示為解答 Q楓仔Q 2009年8月13日 上午 09:11
    2009年8月12日 上午 10:18
    版主

所有回覆

  • 你這樣寫當然會變無限迴圈啊 , Form1執行個體啟始時會New 1 個From2的執行個體, Form2執行個體又會New 1個 Form1的執行個體.
    當然會New個沒完沒了..
    請關心自己的問題,不要問了就放空;這是對別人與自己的尊重
    2009年8月11日 下午 03:44
    版主
  • 您好,有點不懂您說的 [把他改成關閉後Form2也能將資料設定Form1] 

    您試試看以下程式碼

    Form1

    using System;
    using System.Collections.Generic;
    using System.ComponentModel;
    using System.Data;
    using System.Drawing;
    using System.Linq;
    using System.Text;
    using System.Windows.Forms;
    
    namespace WindowsFormsApplication1
    {
        public partial class Form1 : Form
        {
            Form2 f2 = new Form2();
    
            public Form1()
            {
                InitializeComponent();
            }
    
            private void button2_Click(object sender, EventArgs e)
            {
                f2.numericUpDown1.Value = this.numericUpDown1.Value;
            }
    
            private void button1_Click(object sender, EventArgs e)
            {
                f2.f1 = this;
                f2.ShowDialog();
            }
        }
    }
    



    Form2

    using System;
    using System.Collections.Generic;
    using System.ComponentModel;
    using System.Data;
    using System.Drawing;
    using System.Linq;
    using System.Text;
    using System.Windows.Forms;
    
    namespace WindowsFormsApplication1
    {
        public partial class Form2 : Form
        {
            public Form2()
            {
                InitializeComponent();
            }
            public Form1 f1;
    
            private void Form2_FormClosed(object sender, FormClosedEventArgs e)
            {
                f1.numericUpDown1.Value = this.numericUpDown1.Value;
            }
        }
    }
    

    .NET菜鳥自救會 http://www.dotblogs.com.tw/chou/
    2009年8月11日 下午 03:56
    版主
  • hi
    如同Bill Chung 大說的,不要New個沒完沒了(因為Form1初始化同時也實體化Form2,這時換Form2初始化同時也實體化Form1)
    你可以把form是否有實體化的判斷動作寫在click事件中

    public partial class Form1 : Form
        {
            Form2 f2 ;  
            public Form1()
            {
                InitializeComponent();
               
            }

            private void button2_Click(object sender, EventArgs e)
            {            
                 if (f2 == null)
                 {
                   f2 = new Form2(); 
                   f2.numericUpDown1.Value = this.numericUpDown1.Value;
                 }
                 else
                   f2.numericUpDown1.Value = this.numericUpDown1.Value;
            }

            private void button1_Click(object sender, EventArgs e)
            {
                if (f2 == null)
                 {
                   f2 = new Form2(); 
                   f2.ShowDialog();
                 }
                else
                  f2.ShowDialog();
            }  
        }

       form2做法也一樣

    2009年8月11日 下午 04:01
  • 這個問題,問了好多好多次了.
    你們寫成程式都沒有一開始就規劃?
    寫程式要高內具,低耦合.這個學校有教吧?你們這樣寫就高偶合了.
    這只是簡單的二個Form在傳.如果是很多Form,很多Class在傳哪?

    2009年8月12日 上午 12:20
  • Hi,

    我文章上面你的狀況就有寫到
    你沒看仔細吧
    而且文中也有提到Form2控制Form1的做法
    你這樣寫跟沒看文章的寫法好像沒啥兩樣

    我把它節錄出來

    P.S.這邊初學者很容易犯的問題就是會在Form2內再宣告出一個Form1,並對宣告出的Form1做資料互傳,最後的結果當然是資料互傳後結果不如預期。這是因為沒認清物件參考的原因,每宣告一個物件實體作業系統都會分配一塊記憶體空間,因此需認清本來的Form1表單與Form2內新宣告的Form1是不同的物件參考這個事實。

    http://www.dotblogs.com.tw/larrynung/
    2009年8月12日 上午 01:11
  • To 蹂讕 我知道你有寫出來.你的絕對沒錯.你的是很多種解法之一.我雖難不能說是最好的解法.但對你來說寫一隻大程式是沒問題的.
    我是覺得是發問者根本不知道問題的所在.他只會抄Code而已.而這種問題已經發問過很多很多了.
    我是建議,發問者從WindowsForm MSDN的文章一章章的讀一次.MSDN好像很少這樣去傳Form1跟Form2.大部分是用屬性去包.將所要的值用值或參照去傳.而不是將二個Form耦合的死死的.

    2009年8月12日 上午 01:31
  • To 好說

    我是在說Q楓仔Q啦
    感覺文章跳著看
    重點都跳光光了

    當然傳Form是不好的作法
    但要帶出的概念其實一樣
    都是靠Public的成員來互通
    不論是方法,屬性還是欄位都可以
    重要的還是讀者要能融會運用
    不然說再多再深都沒用阿

    http://www.dotblogs.com.tw/larrynung/
    2009年8月12日 上午 01:45
  • 我覺得很多發問者沒去查舊文章.
    很奇怪的問題是可以問的.通用性問題,可以先查舊文章.
    而就這個問題.可以很深到整個系統架構.也可以很淺只解決目前問題.
    而就Form之間傳值.我覺得小朱有幾篇從MSDN範例貼下來的範例Code是最佳的.你們可以去查舊文章.
    2009年8月12日 上午 01:54
  •   謝謝各位前輩的指教,小弟沒經過深思和研讀就發文造成各位的不便非常抱歉,
     
      但是我是看著文章所需所寫的,真的沒有就只是抄code....!! 我是真的不太懂我的問題是出在哪

      我知道他會new新的, 我是疑問我關掉Form2讓值寫回Form1,為什麼會有無限迴圈,我是因為這點納悶才問的

      至於寫程式的規劃因為只是練習所以就沒做程式上的規劃

      文章最後一點沒仔細看是因為我在試改變的寫法時一直偵錯就沒繼續往下看,沒看到下面有提到相關內容

      因為我都是找一些相關書籍練習,再自己加以改變,可能不是每個部分都能完全理解

      但是上述前輩所提到的內容與指教小弟會虛心檢討
      
     
    2009年8月12日 上午 03:23
  • Hi,

    你的問題點跟關不關掉無關
    程式運行就會發生了
    這搞不懂的話就是你對變數初始器沒有認知
    以你的程式來看
    Form1實體建立時會產生Form2 (因為你有加Form2 f2 = new Form2();)
    而Form2被建立後Form1又會建立 (因為Form1 f1 = new Form1();)
    所以你的程式變成
    New Form1=>New Form2=>New Form1=>New Form2....

    http://www.dotblogs.com.tw/larrynung/
    • 已標示為解答 Q楓仔Q 2009年8月13日 上午 09:11
    2009年8月12日 上午 03:37
  • 抄Code就是抄Code.沒什麼大不了的.寫十幾年的老程設師也在抄Code.包含我.
    程式架構要規劃也不是那麼簡單.需要花很多年時間.
    你最先的寫法,那個問題叫遞回參照.A->B,B又參照到A.我不知Form為什麼不會出現錯.如果你寫DLL專案.二支Class互相參照編譯時就錯了.

    • 已標示為解答 Q楓仔Q 2009年8月13日 上午 09:11
    2009年8月12日 上午 03:38
  • 抄Code就是抄Code.沒什麼大不了的.寫十幾年的老程設師也在抄Code.包含我.
    程式架構要規劃也不是那麼簡單.需要花很多年時間.
    你最先的寫法,那個問題叫遞回參照.A->B,B又參照到A.我不知Form為什麼不會出現錯.如果你寫DLL專案.二支Class互相參照編譯時就錯了.


          抄code我知道是正常也一定會有,可能是我誤解前輩的意思,覺得我只會抄code沒自己試做就發文

          所以我才澄清我真的是看著圖和文章所需物件和功能自己寫過

          在這像前輩說聲抱歉,還望前輩不吝指教與教學
    2009年8月12日 上午 03:54
  •    我知道他會new新的, 我是疑問我關掉Form2讓值寫回Form1,為什麼會有無限迴圈,我是因為這點納悶才問的

     
          因為你寫在全域中啊. 產生一個Form的執行個體, 並不代表它一定要Show出來才叫產生,你只要New了這個執行個體就出現了.然後你又 1 產生2 , 2產生1 ......., 所以就會形成一個沒完沒了的迴圈
           還有一個重點: 你每次產生的執行個體雖然是參考同一個Class , 但是它是不同的執行個體.
         

    請關心自己的問題,不要問了就放空;這是對別人與自己的尊重
    • 已標示為解答 Q楓仔Q 2009年8月13日 上午 09:11
    2009年8月12日 上午 10:18
    版主