none
繼承之後表單馬上發生錯誤 RRS feed

  • 問題

  • 由於我要做的程式好幾個表單有許多共同功能因此我想將共用的程式碼做在一個基底表單之後以繼承的方式來節省程式設計的時間但是我基底做好之後用visual studio 的繼承功能繼承基底標單馬上就出錯,以下是我的錯誤訊息:


    1。 隱藏呼叫堆疊
    於 Text.formbase1.formbase1_Load(Object sender, EventArgs e) 於 e:\c#\Text\Text\formbase1.cs: 行 216
    於 System.Windows.Forms.Form.OnLoad(EventArgs e)
    於 System.Windows.Forms.Form.OnCreateControl()
    於 System.Windows.Forms.Control.CreateControl(Boolean fIgnoreVisible)
    於 System.Windows.Forms.Control.CreateControl()
    於 System.Windows.Forms.Control.SetVisibleCore(Boolean value)
    於 System.Windows.Forms.Form.SetVisibleCore(Boolean value)
    於 System.Windows.Forms.Control.set_Visible(Boolean value)
    於 System.Windows.Forms.Design.DesignerFrame.Initialize(Control view)
    於 System.Windows.Forms.Design.DocumentDesigner.Initialize(IComponent component)
    於 System.Windows.Forms.Design.FormDocumentDesigner.Initialize(IComponent component)
    於 System.ComponentModel.Design.DesignerHost.AddToContainerPostProcess(IComponent component, String name, IContainer containerToAddTo)
    於 System.ComponentModel.Design.DesignerHost.PerformAdd(IComponent component, String name)
    於 System.ComponentModel.Design.DesignerHost.System.ComponentModel.Design.IDesignerHost.CreateComponent(Type componentType, String name)
    於 System.ComponentModel.Design.Serialization.DesignerSerializationManager.CreateInstance(Type type, ICollection arguments, String name, Boolean addToContainer)
    於 System.ComponentModel.Design.Serialization.DesignerSerializationManager.System.ComponentModel.Design.Serialization.IDesignerSerializationManager.CreateInstance(Type type, ICollection arguments, String name, Boolean addToContainer)
    於 System.ComponentModel.Design.Serialization.TypeCodeDomSerializer.Deserialize(IDesignerSerializationManager manager, CodeTypeDeclaration declaration)
    於 System.ComponentModel.Design.Serialization.CodeDomDesignerLoader.PerformLoad(IDesignerSerializationManager manager)
    於 Microsoft.VisualStudio.Design.Serialization.CodeDom.VSCodeDomDesignerLoader.PerformLoad(IDesignerSerializationManager serializationManager)
    於 System.ComponentModel.Design.Serialization.BasicDesignerLoader.BeginLoad(IDesignerLoaderHost host) 


    2014年6月9日 下午 06:13

解答

  • 我是已經設計完一個基底表單,可是繼承之後在設計畫面就出現錯誤了

    我的看法就是不要用繼承的,  而是用聚合的設計

    補充: 我解釋的清楚一點好了
    狀況(1) 繼承 Form 類別設計了一個  Form1 類別, 然後再 Form1 類別上面放了某些控制項, 在 Form1 上面加入某些控制項的行為稱為聚合 (以 Controls 屬性的角度來看, 這是組合, 但不論組合或聚合都被稱為合成的設計)

    狀況(2) 承(1), 為了想要重用那些控制項(你可能為它們寫了一些 Code), 設計了一個 Form2 繼承 Form1 , 這種行為叫做繼承

    狀況(3) 為了希望達到在(2) 的重用目的, 我會改變設計方式, 先設計一個 UserControl, 把那些控制項訪進 UserControl 中. 然後 Form1 和 Form2 都是繼承 Form 類別, 只是加入剛剛設計的 UserControl 進來.

    對照 (2) 與 (3) 的作法 , (3) 的作法就是以聚合替代掉 (2)的繼承設計. 這是我比較偏好的方式


    在現實生活中,你和誰在一起的確很重要,甚至能改變你的成長軌跡,決定你的人生成敗。 和什麼樣的人在一起,就會有什麼樣的人生。 和勤奮的人在一起,你不會懶惰; 和積極的人在一起,你不會消沈; 與智者同行,你會不同凡響; 與高人為伍,你能登上巔峰。



    2014年6月10日 上午 04:42
    版主

所有回覆

  • 你覺得網友們會知道 formbase1.cs 行216 是啥?

    以下為簽名檔,如果你愛拉椅子坐那就是你的問題。
    先查MSDN文件庫
    再用GOOGLE搜尋
    才到論壇來發問

    這是論壇不是技術支援中心
    沒有人得無償解答你的問題

    在標題或文章註明很急
    不會增加網友回覆速度

    2014年6月9日 下午 11:16
  • 你可能必須要把重點繼承的方法程式碼部分片段貼出來,並且把關鍵的地方整理出一點資訊,這樣大家才會幫你找到問題。

    開發者的異想世界 - http://etroy-com.blogspot.tw/

    2014年6月10日 上午 01:26
  • 您好,

    請問是設計畫面就發生錯誤嗎?

    可參考 .NET Windows Forms design time rules 看看。


    亂馬客blog: http://www.dotblogs.com.tw/rainmaker/

    2014年6月10日 上午 01:39
  • 樓主問的應該是 Windows Forms 吧 ?

    我本身是非常不喜歡把 UI 透過繼承的方式設計, 因為這樣副作用很多, 除非基底的設計只有簡單的框架 .
    為了重用的原因要這麼設計有幾種方式可以思考.

    (1) 若重用部分有牽涉到 UI, 不如將其拉成一個 UserControl , 這樣就不用繼承 Form, 你只要加入同一個 UserControl 的 Instance 就好.

    (2) 若重用的部分不牽涉到 UI , 那應該設法抽象其內容為一個或多個類別, 由 Form 的程式碼去呼叫.

    PS: 也許有人會問我, 那微軟不是也設計了 Form, UserControl 這些控制項讓開發者繼承使用 ? 當然如果你的程式碼可以寫得和他們的工程師一樣漂亮完整就可以這麼幹, 不然我覺得自己去弄個 UI 來當基底繼承都是一個搞死自己的行為而已.

    再補充一下: 不是甚麼東西都要用繼承來考慮, 聚合在大部分的情境都比繼承要來得適合使用


    在現實生活中,你和誰在一起的確很重要,甚至能改變你的成長軌跡,決定你的人生成敗。 和什麼樣的人在一起,就會有什麼樣的人生。 和勤奮的人在一起,你不會懶惰; 和積極的人在一起,你不會消沈; 與智者同行,你會不同凡響; 與高人為伍,你能登上巔峰。


    2014年6月10日 上午 03:43
    版主
  • 不好意思,由於是第一次發問而且剛學程式設計不太曉得發問需要哪些東西,我會盡快整理出來的
    2014年6月10日 上午 04:03
  • 我是已經設計完一個基底表單,可是繼承之後在設計畫面就出現錯誤了
    2014年6月10日 上午 04:04
  • 我是已經設計完一個基底表單,可是繼承之後在設計畫面就出現錯誤了

    我的看法就是不要用繼承的,  而是用聚合的設計

    補充: 我解釋的清楚一點好了
    狀況(1) 繼承 Form 類別設計了一個  Form1 類別, 然後再 Form1 類別上面放了某些控制項, 在 Form1 上面加入某些控制項的行為稱為聚合 (以 Controls 屬性的角度來看, 這是組合, 但不論組合或聚合都被稱為合成的設計)

    狀況(2) 承(1), 為了想要重用那些控制項(你可能為它們寫了一些 Code), 設計了一個 Form2 繼承 Form1 , 這種行為叫做繼承

    狀況(3) 為了希望達到在(2) 的重用目的, 我會改變設計方式, 先設計一個 UserControl, 把那些控制項訪進 UserControl 中. 然後 Form1 和 Form2 都是繼承 Form 類別, 只是加入剛剛設計的 UserControl 進來.

    對照 (2) 與 (3) 的作法 , (3) 的作法就是以聚合替代掉 (2)的繼承設計. 這是我比較偏好的方式


    在現實生活中,你和誰在一起的確很重要,甚至能改變你的成長軌跡,決定你的人生成敗。 和什麼樣的人在一起,就會有什麼樣的人生。 和勤奮的人在一起,你不會懶惰; 和積極的人在一起,你不會消沈; 與智者同行,你會不同凡響; 與高人為伍,你能登上巔峰。



    2014年6月10日 上午 04:42
    版主
  • 不好意思 我想問一下UserControl 是什麼東西

    我補充一下關於我想完成的程式,我想寫一個基礎的進銷存系統原本我在從主畫面到叫出基礎資料表單所使用的方式是利用toolstrip點擊下去之後將控制項的名稱傳到另一個form去從資料庫拉資料表出來來達到一個form可以顯示不同基礎資料表的功能,但是當我要開始做訂單方面的時候發現沒辦法再以這種方法做到將銷貨、訂單...做到同一個form因此我依照學校老師教的使用繼承方式來做剩下的表單,目前我已經做好基底內容除了共同的控制項外還有一些共通的程式碼

    程式碼的部分:

    存檔:

    cn.Open();
                bs.EndEdit();
                string all = "";
                string all2 = "";
                i = 2;
                TextBox[] texs = new TextBox[] { };
                OleDbCommandBuilder builder = new OleDbCommandBuilder(da);
                OleDbTransaction tran = cn.BeginTransaction();
                OleDbDataReader dr = null;
                DataRowState rowstate = ds.Tables["" + Data].Rows[bs.Position].RowState;
                all = "" + ds.Tables["" + Data].Columns[1].ToString();
                all2 = "@p1";

                while (i < ds.Tables["" + Data].Columns.Count)
                {

                    all += ", " + ds.Tables["" + Data].Columns[i].ToString();
                    i++;
                }
                i = 2;
                while (i < ds.Tables["" + Data].Columns.Count)
                {

                    all2 += ", @p" + i;
                    i++;
                }

                setReadOnly(true);

                if (cn.State == ConnectionState.Closed) cn.Open();
                if (toadd)
                {
                    string cs = "INSERT INTO " + Data + " (" + all + ")VALUES(" + all2 + ")";
                    string cs2 = "select @@IDENTITY";
                    OleDbCommand cmd1 = new OleDbCommand(cs, cn, tran);


                    for (i = 0; i < ds.Tables["" + Data].Columns.Count; i++)
                    {
                        cmd1.Parameters.AddWithValue("@" + i + 1, texs[i]);

                    }
                    if (cn.State == ConnectionState.Closed) cn.Open();
                    cmd1.ExecuteNonQuery();

                    OleDbCommand cmd2 = new OleDbCommand(cs2, cn, tran);
                    long id = Convert.ToInt64(cmd2.ExecuteScalar());
                    ds.Tables[Data].Rows[bs.Position]["" + ds.Tables[Data].Columns[0].ToString()] = id.ToString();
                    ds.Tables[Data].Rows[bs.Position].AcceptChanges();
                    DataRow row = ds.Tables["" + Data].Rows[bs.Position];

                    dr = null;


                    try
                    {
                        dr = cmd2.ExecuteReader();

                        //MessageBox.Show("" + dr.GetValue(0), "", MessageBoxButtons.OK);
                        string cs3 = "select * from 客戶 where " + ds.Tables[Data].Columns[0].ToString() + "=" + dr[0];
                        OleDbCommand cmd3 = new OleDbCommand(cs3, cn, tran);
                        dr = cmd3.ExecuteReader();
                        if (dr.Read())
                            for (i = 0; i < dr.FieldCount; i++)
                                row[i] = dr[i];
                        dr.Close();
                        tran.Commit();
                        row.AcceptChanges();
                        toadd = false;
                    }
                    catch (Exception ex)
                    {
                        dr.Close();
                        tran.Rollback();
                        MessageBox.Show("取得新增之編號時發生錯誤" + ex.Message);

                    }

                    cn.Close();
                }
                else
                {
                    //OleDbCommandBuilder builder = new OleDbCommandBuilder(da);
                    da.Update(ds, "" + Data);
                }
                setReadOnly(true);

            }

    新增:

     private void btnadd_Click(object sender, EventArgs e)
            {
                bs.AddNew();
                setReadOnly(false);
                toadd = true;
            }

    除了存檔(還在修改 尚未完成)程式碼比較多以外,其他控制項大概都跟新增差不多只有少量的程式碼


    • 已編輯 darguan 2014年6月10日 上午 05:54
    2014年6月10日 上午 05:34
  • UserControl <-- 使用者控制項, 所以你可以在方案總管上, 先點選你的專案, 按滑鼠右鍵, 新增項目 -->  使用者控制項

    在現實生活中,你和誰在一起的確很重要,甚至能改變你的成長軌跡,決定你的人生成敗。 和什麼樣的人在一起,就會有什麼樣的人生。 和勤奮的人在一起,你不會懶惰; 和積極的人在一起,你不會消沈; 與智者同行,你會不同凡響; 與高人為伍,你能登上巔峰。

    2014年6月10日 上午 06:01
    版主
  • 找出有類似內容的程式碼, 至少先把它獨立成另一個可共用的方法 . ex: 你的程式碼中不同的 OleDbCommand 個體出現了三次, ExecuteReader 出現了兩次

    在現實生活中,你和誰在一起的確很重要,甚至能改變你的成長軌跡,決定你的人生成敗。 和什麼樣的人在一起,就會有什麼樣的人生。 和勤奮的人在一起,你不會懶惰; 和積極的人在一起,你不會消沈; 與智者同行,你會不同凡響; 與高人為伍,你能登上巔峰。

    2014年6月10日 上午 06:17
    版主
  • 謝謝各位幫我解答,我的問題已經解決了。

    下次提問不會再這麼白癡什麼東西都沒有就直接問。

    感謝各位

    2014年6月10日 上午 10:44
  • 謝謝各位幫我解答,我的問題已經解決了。

    下次提問不會再這麼白癡什麼東西都沒有就直接問。

    感謝各位

    發問也是需要點經驗的, 每次有更進步就好


    在現實生活中,你和誰在一起的確很重要,甚至能改變你的成長軌跡,決定你的人生成敗。 和什麼樣的人在一起,就會有什麼樣的人生。 和勤奮的人在一起,你不會懶惰; 和積極的人在一起,你不會消沈; 與智者同行,你會不同凡響; 與高人為伍,你能登上巔峰。

    2014年6月10日 上午 11:15
    版主