none
form 與form 之間的函式呼叫 RRS feed

  • 問題

  • 請問各位先進! 我在主程式的form1 中寫了許多函式例如:

    public bool Falls_the_color(int size)
    {
    ......................
    }

    然後我再form2中想要呼叫Falls_the_color這一個函式來使用,我該如何實踐呢?


    因為我覺得主程式的函式太多想要把每個特殊的功能個別獨立成一個可供任何程式呼叫的form
    或者Program.cs 該如何實踐呢? 不然全部的程式都寫在一個主程式內有點難維護.

    抑或我想要在form2呼叫form1的image 設定process_image.Width,這該如何實踐呢?


    希望各位先進能不吝嗇的給予以指導!
    2009年3月25日 上午 04:54

所有回覆

  • 會共同使用的函式,建議你另外獨立成一個Class來處理,宣告靜態變數就可以達到你要的效果
    從一個Form去呼叫另一個Form的函式有時會造成很多麻煩

    2009年3月25日 上午 05:20
    版主
  • 真的很難,真的很難.
    寫程式盡量將商業邏輯跟UI拆開,將商業邏輯包成Class 去傳資料,讓Form 跟 Form 將偶.
    你這個只要將 Form1.Image 傳到  form2的建構元就好了.



    public class Form2:Form{
         private Image form1Img;
         public Form2(Image img){
             form1Img=img;
         }
    }


    public class MainForm:Form{
           
              private void Form2ShowClick(object sender,EventArgs arg){
                        Form2 form2=new Form2(this.ImgControl);
                                 forms.Show();
            }
    }
    2009年3月25日 上午 06:07
  • 蹂躝的方式簡單,但...對一個救急的還不錯用.
    但:
    1.你將所有Controls 開成 Public 有安全的疑慮.通常要用屬性去包再去驗證內容.
    2.你二個Form 間耦合太多,也就是FormB 可能直屬於 FormA 就不懂得 FormC.
    3.如果 FormA 的內容動了,FormB 會不會連動?反之FormB 內容變了,FormA 會不會反應.
    4.用Static 是否浪費太多的空間了.
    2009年3月25日 上午 08:20
  • 嗯..我知道
    關於第一點
    Form2.NumericUpDown1是因為表單拉完後沒改
    所以預設是可以直接讀到的
    就直接拿來用了...
    而Form2.MainForm我範例是寫成屬性..可能文章忘了改了
    這些可能要再描述的更清楚些

    第四點則只是提個方法..我也有特別註記不建議使用
    只是把能達到該目的的方法統整一下

    至於您提到的第二、三點我有點看不懂..可否能描述的更為詳細呢?
    2009年3月25日 上午 09:13
  • 大概看懂了
    不知好說大大所說的
    是否是因為我把Form1參考傳給Form2
    而這樣做必須Form2能認得Form1類別
    Form1的改變也會影響到Form2的使用
    2009年3月25日 上午 09:36
  • 關於第二點,就如 .Net Framework 的許多對話盒一樣.這些對話盒是給很多程式,表單使用.
    如果你沒有降偶,就是表單A跟表單B關係很緊的話,你這樣你整個系統就會有多的這種子表單,非常難維護.
    第三點.程式跟程式間是傳資料而不要傳控制項.資料物件跟控制項用DataBinding的方式.二個控制項蓮到同一個DataBinding 時當某個控件轉換某個資料狀態,她會回寫到原來的DataSource,然後DataBinding 就會通知所有UI,控制項...去更新顯示.而你在操作時只要修改資料來源UI就變化,這樣妳就不用為了一個值去找某個控件了.
    比如說(討論區最常見的) DataGridView 裡包 DataGridView 包 ListBox 再包ComboBox.今天我要找 ComboBox 的值. 告訴你你要找到這個值,寫到哭你都還不一定取的出. 

    2009年3月25日 上午 09:58
  • 不過我文章中方法一下方也有提到
    上面直接傳表單是簡單的寫法
    但不建議使用
    也有提到耦合的問題
    而下面我有用事件來達成同樣的效果

    而傳控制項與傳資料
    我也不是說沒考慮到
    只是怕我封裝弄太多
    初學者反而會看不懂
    因此我只帶出個觀念
    怎摸運用就看他們怎樣吸收

    您的建議我會參考
    看怎樣才能讓初學者能夠吸收
    又能顧及到所有方面
    內容我會再慢慢的補上去
    很感謝您的指教
    2009年3月25日 上午 10:08
  •  蹂躪 大大 ,你們是老師嗎!真佩服你們的用心.我只會打嘴砲而已,叫我教,算了口齒不清.
    在這裡我做幾個概念的分享.
    1.寫Class or form 要有封裝的效果,所謂封裝就是該對外面通訊才Public,不然就用Private.為什麼,你有看過一隻Class有好幾千個屬性,方法嗎?,你開的越多越難用,而每個Public 是 Property 而不要是  Field,而每個輸入都要有Check的動作.

    2.Class or Form 之間要低偶合,所謂低偶合就是 A跟B之間的關係越小越好.怎麼將偶那?就是你在設計門面(方法),介面的通道越小越好.比如我今天要FormB 去修改 FormA的TextBoxA ,我今天設計 FormB去接收 FormA,那我真的只能改 FormA裡的TextBoxA. 如果我今天改一下 FormB去接TextBox的參數,我FormB就可以去改 FormA的TextBoxA,TextBoxB 或 FormC的TextBox.
    接著第二個降偶的方式,是用第三方物件去傳參數.(範例還在思考中).
    第三個比較複雜一點.比如說我 FormB 要執行 FormA 裡面三個方法.這個你就要將這三個方法去抽象化或介面化後當成參數去傳.
    Exp: 我FormB 是做列印對話盒的動作.功能是要做印表機參數設定,列印的內容取自FormA的三個方法.所以你將三個方法取出並產生IPrint的介面,你列印時只要將IPrint 參數傳到 FormB就可以列印.而今天我要列印FormC,我也只要FormC實作IPrint 就可以列印FormC.

    3.2個Control間內容要同步,動 ControlA ,ControlB連動,底層商業物件內容連動.這個你們要去學DataBinding 的物件及IPropertyChange.ICollectionChange(上面二個介面名稱可能不很正確,你們要在驗證一下).
    有了這些,你就可以將資料庫或其它來源的資料Binding 到 Control 呈現,你在UI的修改會自動更新其他的畫面,及底層的資料來源.
    2009年3月26日 上午 01:22
  • 接著在討論一個常見的問題.
    FormA 參考 FomB,FormB 參考 FormC ,FormA.FormC 參考FormB,FormA...這種狠雜的遞回參照的問題.這個對初學者我想不清楚是什麼,但對資深一點的就知道嚴重性.
    我們寫程式的時候 就只能單一參照 FormA->FormB->FormC->BizObj->DataAccess這種方式.
    而我們要時做就有點困難度.為什麼有困難度,因為我ClassA 去參考 ClassB 通常已經知道 ClassB 裡的方法.反過來 ClassB 裡面根本不知ClassA裡面的方法.所以你在做時你就要ClassA去呼叫ClassB的方法傳參數,而ClassA要去訂閱ClassB的事件. 也就是ClassA 丟參數到 ClassB是透過方法.而 ClassB 丟參數到 ClassA是透過事件.
    2009年3月26日 上午 01:35
  • 真的很感謝大家! 沒想到我原本以為因該是小問題的問題! 可以引起大家的討論,小弟受教了!  
    2009年3月26日 上午 04:31
  • 我不是老師阿~沒有那麼嫩的老師吧
    只是發現自己年老..記憶大不如前..就先把腦中的資料存到部落格
    其實您的概念與例子都相當不錯~相信這篇能對開發經驗不足的初學者有不少的助益
    2009年3月27日 下午 03:40
  • 話說回來

     

    form 與 form 之間傳資料, vb.net 方便得多..

     

    只須  form1. textbox1.text = xxx  

    form2.label1.text = xxx

    form5.button1.text = xxx

     

    特別一個程序內需要很多 win form 時... 在 C# 單是搞這些無意義的功夫, 也消磨掉設計主體程序的意志!

    2011年5月18日 下午 04:03
  • 話說回來

     

    form 與 form 之間傳資料, vb.net 方便得多..

     

    只須  form1. textbox1.text = xxx  

    form2.label1.text = xxx

    form5.button1.text = xxx

     

    特別一個程序內需要很多 win form 時... 在 C# 單是搞這些無意義的功夫, 也消磨掉設計主體程序的意志!


    Visual Basic之所以可以這樣用, 是基於很特別的原因, 因為要讓VB6的使用者可以覺得差距沒這麼大.

    而且你知道是哪個機制讓Visual Basic可以這樣用的嗎 ?

    在物件導向設計概念中, 其實C#的作法才是較為符合原則的, 這並不叫做無意義. 

    我是個使用Visual Baisc的人, 但不得不說, Visual Basic這個看似方便的功能卻會讓很多人的物件導向概念模糊掉.

    2011年5月18日 下午 04:37
  • 話說回來

     

    form 與 form 之間傳資料, vb.net 方便得多..

     

    只須  form1. textbox1.text = xxx  

    form2.label1.text = xxx

    form5.button1.text = xxx

     

    特別一個程序內需要很多 win form 時... 在 C# 單是搞這些無意義的功夫, 也消磨掉設計主體程序的意志!


    Visual Basic之所以可以這樣用, 是基於很特別的原因, 因為要讓VB6的使用者可以覺得差距沒這麼大.

    而且你知道是哪個機制讓Visual Basic可以這樣用的嗎 ?

    在物件導向設計概念中, 其實C#的作法才是較為符合原則的, 這並不叫做無意義. 

    我是個使用Visual Baisc的人, 但不得不說, Visual Basic這個看似方便的功能卻會讓很多人的物件導向概念模糊掉.

    VB 可以這樣做, 其實原因在那裏?

     

    不過作為程序編寫, 方便亦很重要

    2011年5月18日 下午 04:58
  • 原因我已經寫了, 機制的提示就是My.Forms

    因為這個方便, 使得很多人真的要寫較為深入的物件導向程式時就會在觀念上出現障礙.

    所以我並不認為你對C#的看法是成熟的.

    2011年5月18日 下午 05:12
  • 話說回來

    form 與 form 之間傳資料, vb.net 方便得多..

    只須  form1. textbox1.text = xxx  

    form2.label1.text = xxx

    form5.button1.text = xxx

    特別一個程序內需要很多 win form 時... 在 C# 單是搞這些無意義的功夫, 也消磨掉設計主體程序的意志!

    Hi,

    這句話我不能認同

    以你的範例來看你只是未把界面上的元件其Modify屬性設成Private

    這在C#中也是可以這樣做的

    文章中也有提到這樣的作法

    這樣的作法其問題是並未善用物件導向的封裝特性

    程式也跟界面藕合在一起

    叫用者必須知道你的元件是甚麼

    並直接對元件下去控制

    若界面上的元件更動

    叫用者也必須隨之更動


    謙卑學習,持之以恆,才能不斷的Level Up http://www.dotblogs.com.tw/larrynung/
    2011年5月19日 上午 01:56
  • 話說回來

     

    form 與 form 之間傳資料, vb.net 方便得多..

     

    只須  form1. textbox1.text = xxx  

    form2.label1.text = xxx

    form5.button1.text = xxx

     

    特別一個程序內需要很多 win form 時... 在 C# 單是搞這些無意義的功夫, 也消磨掉設計主體程序的意志!

    這跟語法沒有關係,這是NET控制項的設定而已,所以在C#,C++裡也可以這樣做,但不建議用此招把所有的元件都公開

    秘訣無它,唯勤而已 http://www.dotblogs.com.tw/yc421206/
    2011年5月19日 上午 02:08
  • 每一種程式語言,每一種時代的語言,其語法,設計概念...都不同.

    如果你拿C#的寫法去JAVA,C++..討論區絕對被批.

    拿WP7去跟Android,IOS討論絕對死.

     

    VB時代跟現在差多久.

    也許當時VB 沒有很強的OO概念,沒有多層的架構,沒有雲端..

    可能當時的VB開發人員只寫幾隻表單,一人開發一個系統等等.

    你愛怎麼寫就怎麼寫,沒差(當時的人真幸福).

     

    現在的系統非常複雜,非常多人開發.你沒一套規範是行不通的.

    如果你沒做Interface.只要有人去改基層的架構,如MethodName.我只能說其他的人可以下班了.因為大家等系統重建.

    也可能昨天你下班前是好的,今天早上要Demo系統Run不起來.

    如果你開發企業物件沒Public,Private..你Public太多,使用者看你的物件就非常複雜,也不會用.

    如果你開發WebService 你Public太多,就等著被駭客攻擊...

     



    2011年5月19日 上午 06:35
  • 話說回來

    form 與 form 之間傳資料, vb.net 方便得多..

    只須  form1. textbox1.text = xxx  

    form2.label1.text = xxx

    form5.button1.text = xxx

    特別一個程序內需要很多 win form 時... 在 C# 單是搞這些無意義的功夫, 也消磨掉設計主體程序的意志!

    Hi,

    這句話我不能認同

    以你的範例來看你只是未把界面上的元件其Modify屬性設成Private

    這在C#中也是可以這樣做的

    文章中也有提到這樣的作法

    這樣的作法其問題是並未善用物件導向的封裝特性

    程式也跟界面藕合在一起

    叫用者必須知道你的元件是甚麼

    並直接對元件下去控制

    若界面上的元件更動

    叫用者也必須隨之更動


    謙卑學習,持之以恆,才能不斷的Level Up http://www.dotblogs.com.tw/larrynung/


    請問, 如果最簡單的操作, 要在 form1, form2, form3 的 textBox1_TextChanged 事件內都可,

    1) 啟動 form2.show() 這一個動作,

    2) 改 form2.label1.text

    最簡單是怎樣做?

    我現在的方法如下, 做一個 class, static 所有 forms

     public static class Program
        {
            /// <summary>
            /// 應用程式的主要進入點。
            /// </summary>
            [STAThread]

             static void Main()
            {

                Application.EnableVisualStyles();
                Application.SetCompatibleTextRenderingDefault(false);
                //Application.Run(new Form1());
                MyForms forms = new MyForms();
                forms.inti();           
                Application.Run(MyForms.form1);          
               
            }
        }

        public class MyForms
        {
            public static Form1 form1;
            public static Form2 form2;
            public void inti()
            {
                form1 = new Form1();
                form2 = new Form2();           
            }
        }

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

            private void textBox1_TextChanged(object sender, EventArgs e)
            {
                MyForms.form1.changeLabel1(textBox1.Text);           
            }
        }

     

    再在 Form1 class 內, 加一個

    public changeLabel1(string tx)

    {label1.text = tx;}





    2011年5月23日 下午 06:26
  • Hi,

    如果只講求方便

    Static自然是最方便的

    用你的方法自然可行

    另外也可以建立個靜態的控管類別

    搭配反射技術實現

    避免增減表單就需要頻繁修改類別

    或是用擴充方法為特定類別實現GetSingleTonInstance方法

    透過該方法取得相同的物件實體


    謙卑學習,持之以恆,才能不斷的Level Up http://www.dotblogs.com.tw/larrynung/
    2011年5月24日 上午 04:35