none
如何在靜態方法中 去修改控制項如FORM,TEXTBOX,或是BUTTON (需要有物件參考才能使用非靜態欄位、方法或屬性 ) RRS feed

  • 問題

  • 需要有物件參考才能使用非靜態欄位、方法或屬性

    這是我的錯誤訊息 

    方法是作在form1裡面,我該如何指向designer去修改控制項

    因是第一次利用 vs 所以不清楚之間的關聯
    2009年4月28日 上午 06:03

解答

  • 如果確定 Form B 只有一個的話, 有另外一種偷懶的方法, 也許適合你的狀況:

    在 Form B 內增加下面宣告

    static B g_B;

    然後在 B 的 Constructor 內加入

    g_B = this;

    這樣就可以把 Form B 的 instance 存在 g_B 這個 static 變數, 所以在 thread2() 內就可以用 g_B 直接存取到該 instance, 如:

    g_B.Text = ID;
    • 已提議為解答 Todd Chen 2009年4月29日 上午 01:44
    • 已標示為解答 TigerHsu 2009年4月29日 上午 02:28
    2009年4月29日 上午 01:43
  • 正確的解法可以改用 ParameterizedThreadStart, 就是如 蹂躪 所提的方式, 需修改兩處:

    將 

    stb = new Thread(new ThreadStart(thread2));
    stb.Start();

    改成

    stb = new Thread(new ParameterizedThreadStart(thread2));
    stb.Start(this);


    public static void thread2()

    改成

    public static void thread2(object sender)

    接著在 thread2 中, 就可以把 sender 轉型為 B 直接來作操作, 如:

    B instance = (B)sender;
    instance.Text = ID;

    • 已提議為解答 Todd Chen 2009年4月29日 上午 02:52
    • 已標示為解答 TigerHsu 2009年4月29日 上午 03:42
    2009年4月29日 上午 02:52

所有回覆

  • 你應該是這樣用
    Button.Text = "按鈕";

    所以錯誤

    原因很簡單,Button指得是你畫面哪個按鈕?
    所以每個按鈕應該都有個Id.譬如說button1,button2.
    而程式應該用
    button1.Text = "按鈕";

    你應該是剛接觸Windows程式設計的新手,建議你先買本.Net Windows部分的書籍來研讀.
    2009年4月28日 上午 09:28
  • 這是我的完整的程式碼

    利用bt1進行連線
    我再bt1的觸發時就可以明確的控制那些控制項,但是在連線後開啟的多工裡卻無法明確的指向控制項




    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;
    using System.Threading;
    using System.Net;
    using System.Net.Sockets;


    namespace Clin
    {
        public partial class B : Form
        {
            static Socket conn;
            static Thread stb = new Thread(new ThreadStart(thread2));
            static string message;
            static string ID;
           

            public B()
            {
                InitializeComponent();
            }

            private void B_Load(object sender, EventArgs e)
            {
                tb1.Text = "請輸入名子";
            }

            private void bt1_Click(object sender, EventArgs e)
            {
                string name = "Tiger";
                IPHostEntry add = Dns.GetHostByName(name);
                IPAddress[] ipadd = add.AddressList;
                IPEndPoint host = new IPEndPoint(ipadd[0], 7200);
                conn = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
                conn.Connect(host);
                stb = new Thread(new ThreadStart(thread2));
                stb.Start();

                this.Text = "等待其他用戶端連線";
                bt1.Visible = false;
                String str1 = "P" + tb1.Text;
                ID = tb1.Text;
                Byte[] buff1 = Encoding.Unicode.GetBytes(str1);
                conn.Send(buff1, buff1.Length, 0);

            }


            public static void thread2()
            {
                Socket client=conn;                 
                 int length;                              
                byte[] buff = new byte[1000] ;
                while (true)
                {
                   
                    length = client.Receive(buff, 1000, 0);                           
                    message=Encoding.Unicode.GetString(buff,0,length);
                    if (message.Substring(0, 1) == "S")
                    {
                        this.bt1.Size = new System.Drawing.Size(0, 0);  //這三行會出現錯誤
                        this.Size = new System.Drawing.Size(400, 400);  //(需要有物件參考才能使用非靜態欄位、方法或屬性)
                       
    this.Text = ID;
                    }
                }
            }

        }
    }

    2009年4月29日 上午 01:11
  • 靜態方法為類別層級的方法
    可在未宣告物件實體的狀態下使用
    因此不能使用this

    http://www.dotblogs.com.tw/larrynung/
    2009年4月29日 上午 01:14
  • 我該如何才能在靜態方法中 修改那些控制項呢?
    2009年4月29日 上午 01:19
  • 需傳入物件參考
    透過物件參考控制
    可能如下
    public static void thread2(Class b)
            {
                Socket client=conn;                 
                 int length;                              
                byte[] buff = new byte[1000] ;
                while (true)
                {
                    
                    length = client.Receive(buff, 1000, 0);                            
                    message=Encoding.Unicode.GetString(buff,0,length);
                    if (message.Substring(0, 1) == "S")
                    {
                        b.bt1.Size = new System.Drawing.Size(0, 0);  
                        b.Size = new System.Drawing.Size(400, 400);  
                        b
    .Text = ID;
                    }
                }
            }

    http://www.dotblogs.com.tw/larrynung/
    2009年4月29日 上午 01:21
  • 如果確定 Form B 只有一個的話, 有另外一種偷懶的方法, 也許適合你的狀況:

    在 Form B 內增加下面宣告

    static B g_B;

    然後在 B 的 Constructor 內加入

    g_B = this;

    這樣就可以把 Form B 的 instance 存在 g_B 這個 static 變數, 所以在 thread2() 內就可以用 g_B 直接存取到該 instance, 如:

    g_B.Text = ID;
    • 已提議為解答 Todd Chen 2009年4月29日 上午 01:44
    • 已標示為解答 TigerHsu 2009年4月29日 上午 02:28
    2009年4月29日 上午 01:43
  • 嗯...這樣也可以
    不過使用上會有所限制
    需特別注意

    使用上記得要有建立實體才能使用
    不然該屬性會是Nothing
    直接使用就會掛掉

    若是建立實體後
    實體已銷毀
    該屬性雖不為Nothing
    也不能直接使用

    http://www.dotblogs.com.tw/larrynung/
    2009年4月29日 上午 01:55
  • 您說這是一個偷懶的做法,只能針對只有一個form B

    那正確的應該如何使用呢?

    2009年4月29日 上午 02:29
  • 你的問題若是只能建立一個Form B
    每個表單不需傳遞物件參考就可以直接控制Form B
    那也許套用SingleTon Design Pattern會比較適當

    http://www.dotblogs.com.tw/larrynung/
    2009年4月29日 上午 02:40
  • 正確的解法可以改用 ParameterizedThreadStart, 就是如 蹂躪 所提的方式, 需修改兩處:

    將 

    stb = new Thread(new ThreadStart(thread2));
    stb.Start();

    改成

    stb = new Thread(new ParameterizedThreadStart(thread2));
    stb.Start(this);


    public static void thread2()

    改成

    public static void thread2(object sender)

    接著在 thread2 中, 就可以把 sender 轉型為 B 直接來作操作, 如:

    B instance = (B)sender;
    instance.Text = ID;

    • 已提議為解答 Todd Chen 2009年4月29日 上午 02:52
    • 已標示為解答 TigerHsu 2009年4月29日 上午 03:42
    2009年4月29日 上午 02:52
  • 非常感謝您的解答,不知道您當初是如何學會c#以及運用vs(我目前是安裝2008)

    是否有容易參考程式碼的書籍或是完整介紹vs c#的書(針對c#),可以介紹一下嗎?
    2009年4月29日 上午 05:34