-1

私はまったく新しいものC#で、3つの異なるフォームに1つの共通シリアルポートを使用しようとしています:Form2, Form3, Form4

Form1.cs他のフォームのプログラムを起動するために必要なだけなので、これには必要ありません。基本的に、3 つのフォームはすべて同じシリアル ポートから同時にデータを受信する必要があります。私が直面している問題は、シリアル ポートからデータを受信できるのは 1 つのフォームだけで、他の 2 つのフォームは受信できないことです。

次のような質問を見つけました。

2 つの異なるフォームで同じシリアル ポート データ受信イベントを使用する

その問題は私と似ていますか?はいの場合、前述のリンクのサンプル コードをコード内のどこに配置すればよいですか?

誰かがこれを手伝ってくれますか?前もって感謝します!

フォーム1:

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

    private void button1_Click(object sender, EventArgs e)
    {
        Form2 f2 = new Form2();
        f2.Show();
        Form3 f3 = new Form3();
        f3.Show();
        Form4 f4 = new Form4();
        f4.Show();
    }

    private void button2_Click(object sender, EventArgs e)
    {
        this.Close();
    }
}

フォーム2:

public partial class Form2 : Form
{
    GMapControl MainMap = new GMapControl();
    //Initialise data type for latituide and longitude
    double lat, lng;
    //Initialise customise marker (plane maker). Declared as m.
    GMapMarkerImage m = new GMapMarkerImage(new PointLatLng());
    GMapOverlay overlayOne;

    public Form2()
    {
        InitializeComponent();

        SuspendLayout();

        overlayOne = new GMapOverlay(MainMap, "OverlayOne");
        MainMap.MapProvider = GMapProviders.YahooMap;

        MainMap.SetCurrentPositionByKeywords("Singapore");
        MainMap.MinZoom = 1;
        MainMap.MaxZoom = 24;
        MainMap.Zoom = 13;
        MainMap.CanDragMap = true;
        MainMap.DragButton = MouseButtons.Left;
        MainMap.Dock = DockStyle.Fill;
        MainMap.Manager.Mode = AccessMode.ServerAndCache;

        Controls.Add(MainMap);
        ResumeLayout(true);


    }

    public void button1_Click(object sender, EventArgs e)
    {
        if (!serialPort1.IsOpen)    //if serial port is not open
            try
            {
                serialPort1.Open(); //Open Serial Port
                if (lat != 0 && lng != 0)  //Display marker only when GPS has receive data
                {
                    overlayOne.Markers.Add(m);          //Add marker on the position given to the overlayOne layer
                    MainMap.Overlays.Add(overlayOne);   //Add overlayOne layer to the MainMap layer
                }
            }
            catch
            {
                //A message box will display this message, informing user either a wrong port has been chosen, or have not been plugged in.
                MessageBox.Show("There was an error. Please make sure that the correct port was selected, and the device, plugged in.");
            }

    }

    public void button2_Click(object sender, EventArgs e)
    {
        if (serialPort1.IsOpen)                // if Serial Port is open
        {
            serialPort1.Close();               //Close Serial
            overlayOne.Markers.Remove(m);
        }
    }

    //When microsoft visual studio receive data
    public void serialPort1_DataReceived(object sender, System.IO.Ports.SerialDataReceivedEventArgs e)
    {
        this.Invoke(new EventHandler(DoUpdate));    //for function DoUpdate

        //Pause Microsoft Visual Studio for 100 milliseconds from receiving data, 
        //to ensure serialPort can be close successfully
        Thread.Sleep(100);
    }

    //Function for updating data. Declared as DoUpdate.
    public void DoUpdate(object sender, EventArgs e)
    {
        string[] c = serialPort1.ReadLine().Split(',');  //Stored data seperately by using array & using the Split() function

        lat = Convert.ToDouble(c[9]);               //Convert Latitude string data to double data
        lng = Convert.ToDouble(c[10]);              //Convert Longitude string data to double data

        //Input lat and lng data in m.
        //Updating the position of the marker
        m.Position = new PointLatLng(lat, lng);

    }
}

フォーム3:

    public partial class Form3 : Form
    {
        public Form3()
        {
            InitializeComponent();

        }

        private void pictureBox1_Click(object sender, EventArgs e)
        {
            if (!serialPort1.IsOpen)    //if serial port is not open
                try
                {
                    serialPort1.Open(); //Open Serial Port

                    //Enable blocks to have colour
                    // ...
                }
                catch
                {
                    //A message box will display this message, informing user either a wrong port has been chosen, or have not been plugged in.
                    MessageBox.Show("There was an error. Please make sure that the correct port was selected, and the device, plugged in.");
                }

        }

        private void button2_Click(object sender, EventArgs e)
        {
            if (serialPort1.IsOpen)                // if serial port is open
            {
                serialPort1.Close();                   // Close serial Port 

                //Clear data in textboxes
                FrontSonar.Text = "    ";
                LeftSonar.Text = "   ";
                RightSonar.Text = "    ";

                //Clear colours in the boxes
                // ...
            }
        }

        private void serialPort1_DataReceived(object sender, System.IO.Ports.SerialDataReceivedEventArgs e) //When microsoft visual studio receive data
        {
            this.Invoke(new EventHandler(DoUpdate1)); //To update and ensure sonar data infront of UAV can be displayed without error
            this.Invoke(new EventHandler(DoUpdate2)); //To update and ensure sonar data left side of UAV can be displayed without error
            this.Invoke(new EventHandler(DoUpdate3)); //To update and ensure sonar data on the right side of UAV can be displayed without error

            Thread.Sleep(100);
        }

        private void DoUpdate1(object s, EventArgs e) //Display for Sonar infront of UAV
        {
            string[] c = serialPort1.ReadLine().Split(',');  //Stored data seperately by using array & using the Split() function
            FrontSonar.Text = c[1] + "\n";
            double d = Convert.ToDouble(c[1]);

            if (d > 500)
            {
                //Fill blocks with green
                this.rectangleShape1.FillColor = System.Drawing.Color.Green;
                this.rectangleShape2.FillColor = System.Drawing.Color.Green;
                this.rectangleShape3.FillColor = System.Drawing.Color.Green;
            }
            else
                if (d > 400 && d <= 500)
                {
                    //Fill block with Orange colour
                    this.rectangleShape1.FillColor = System.Drawing.Color.Orange;
                    this.rectangleShape2.FillColor = System.Drawing.Color.Orange;

                    //Fill block with Lavender colour
                    this.rectangleShape3.FillColor = System.Drawing.Color.Lavender;
                }
                else
                    if (d <= 400)
                    {
                        //Fill block with red colour
                        this.rectangleShape1.FillColor = System.Drawing.Color.Red;

                        //Fill block with Lavender colour
                        this.rectangleShape2.FillColor = System.Drawing.Color.Lavender;
                        this.rectangleShape3.FillColor = System.Drawing.Color.Lavender;
                    }

        }


        private void DoUpdate2(object s, EventArgs e) //Display for Sonar on the left side of UAV
        {
            string[] c = serialPort1.ReadLine().Split(',');  //Stored data seperately by using array & using the Split() function
            // ....

        }

        private void DoUpdate3(object s, EventArgs e) //Display for Sonar on the right side of UAV
        {
            string[] c = serialPort1.ReadLine().Split(',');  //Stored data seperately by using array & using the Split() function
            // ...
        }    
    }

Form4: (まだ進行中)

public partial class Form4 : Form
{
    public Form4()
    {
        InitializeComponent();
    }
}
4

1 に答える 1

1

はい、できます。以下は、これを達成するための重要なポイントです。

  1. シリアル ポートを 1 回開きます。アプローチif (!port.IsOpened) { port.Open(); }は正しいです。これを静的メソッドで抽出し、各フォーム (f2、f3、f4) で呼び出して、このコード スニペットのコピー/貼り付けを回避します。

  2. serialPort変数は 3 つのフォームすべてで共有する必要があるため、開いて初期化された同じポート インスタンスにすべてのフォームからアクセスできます。あなたが提供したコードを考慮して、作成して初期化し、Form1クラスでポートを開き、コンストラクター注入を介してserialPortの初期化されたインスタンスを他のフォームクラスに渡し、基本的にクラスSerialPort portのコンストラクターパラメーターを追加Form2,3,4してから:

    // renamed button1_Click
    private void OnSetup(object sender, EventArgs e)
    {
        this.port = new SerialPort(...);
        // TODO: initialize port
    
        Form2 f2 = new Form2(this.port);
        f2.Show();
        Form3 f3 = new Form3(this.port);
        f3.Show();
        Form4 f4 = new Form4(this.port);
        f4.Show();
    }
    
  3. 次に、各フォームコンストラクターでserialPort.DataReceivedイベントをサブスクライブするだけです。

    public Form2(SerialPort port)
    {
         port.DataReceived += ...
    }
    

いくつかの推奨事項、

  • 、 、、ではなく、変数とメソッドにわかりやすい名前を付けform1ます。form2cdbutton2_Click
  • マジック ナンバーを避け、変数内の定数を抽出し、説明的な名前を付け400ます500
  • あなたが言っているコードへのコメントでPause Microsoft Visual Studio...microsoft visual studio receives data...、これは正しくありません。アプリケーションの実行 (Visual Studio ではない) は一時停止Thread.Sleep()され、applciation は着信シリアル ポート データを受け取ります。Visual Studio は単なる開発環境であり、そのような場合ポート通信には直接関与しません。
于 2012-09-27T08:37:32.873 に答える