0

私は C# の初心者ですが、Head Start C# のチュートリアル ブックをゆっくりと読んでいます (そして、これまでのところ非常に楽しいと感じています)。ただし、最初の「ラボ」課題で壁にぶつかりました。PictureBox を制御するためのコードが提供され、そのコードをメイン フォームで動作させることはできますが、クラス内から動作させることはできません。 . 私は古いレッスンに戻って、何が欠けているかについてかなり良い考えを持っていますが、私の人生では、クラス内からメインフォームのPictureBoxにアクセスする方法を理解できません(チュートリアルが私がすべきだと言っているように)。

私は本を​​まったく先に進めていなかったので、少しイライラしますが、これはまだカバーしていないことを誓います. とにかく、本物のプログラマーには魅力的です。

チュートリアルで提供されているコードは次のとおりです。「オブジェクトはフォーム上のものを制御できます」(本を持っている人は p208) というセクションにあります。

Point p = MyPictureBox.Location 
p.x += distance;
MyPictureBox.Location = p

以下に、コードの関連する (私が思うに?) 部分を投稿します。Button1 はコンパイル時に機能し、Button2 は「機能」します。つまり、現在のクラスは、渡された INT を出力するように指示するだけです。これは、機能しないコードをコメントアウトしたためです。

前もって感謝します!

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;
// Namespaces I'll need.

namespace Troubleshooting_PicBoxes
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent(); // Start all the Form1 stuff (all IDE-generated)

    }

    private void button1_Click(object sender, EventArgs e) //method from clicking the first button
    {
        int distance = 5; // Create this variable called "distance"

        Point BoxMovement = MyPictureBox.Location; //create a point called BoxMovement

        BoxMovement.X += distance; // Adjust the X of BoxMovement by my distance int.

        MyPictureBox.Location = BoxMovement; // now adjust the Box by the Point's location.

    }

    private void button2_Click(object sender, EventArgs e)
    {
        PicMover PicMoverObject1 = new PicMover(); // Reserve Space for&Create object
        PicMoverObject1.MoveThatPic(5); // Execute Object Method with a value of 5




    }


}
}

PicMover クラスのコード:

//

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 Troubleshooting_PicBoxes
{
class PicMover
{


    public void MoveThatPic(int distance) // New method, 
                                          // takes a variable called Distance.

    {
        MessageBox.Show(distance.ToString()); // Just show us that Variable.


        // I need to be able to access Form1's picture box before I can use this. :(
        /*           Point BoxMovement = MyPictureBox.Location; //create a point called BoxMovement
                    BoxMovement.X += distance; // Adjust the X of that by distance.
                    MyPictureBox.Location = BoxMovement; // now adjust the Box by the Point's location.
        */


    }
}

}

4

3 に答える 3

1

何かにアクセスする必要がある場合は、アクセスを許可してみませんか? メソッドに引数として渡すようなものです。

public void MoveThatPic(PictureBox picBox, int distance) // New method, 
                                      // takes a variable called Distance.

{
    MessageBox.Show(distance.ToString()); // Just show us that Variable.


    // I need to be able to access Form1's picture box before I can use this. :(
    Point BoxMovement = picBox.Location; //create a point called BoxMovement
    BoxMovement.X += distance; // Adjust the X of that by distance.
    picBox.Location = BoxMovement; // now adjust the Box by the Point's location.
}

button2 のクリック イベント ハンドラーで:

private void button2_Click(object sender, EventArgs e)
{
    PicMover PicMoverObject1 = new PicMover(); // Reserve Space for&Create object
    PicMoverObject1.MoveThatPic(MyPictureBox, 5); // Execute Object Method with a value of 5
}
于 2009-12-22T01:55:12.300 に答える
0

チュートリアル コードは、クラス (MyPictureBox.Location) から場所を取得し、場所を変更してから、オブジェクトをその新しい場所に移動しているように見えます。

Point p = MyPictureBox.Location // Save the location of your object
p.x += distance; // Increase the distance
MyPictureBox.Location = p // Set your object to the new location

2 番目のボタン プレス イベントは異なります。おそらく、関数から場所を返す必要がありますか? そのため、関数を呼び出すときに、メイン フォームの PictureBox を返された値に設定します。

于 2009-12-22T02:13:10.547 に答える
0

任意の Form からアクセスできる汎用クラスを作成し、そのインスタンスを作成し、その Form 上の任意の PictureBox を移動する場合は、「Deerchao の回答がその方法を示しています。

ただし...考えてみてください...すべての Form は、 PicMover の独自のインスタンスを宣言する必要があります。Form1 の PicMover のインスタンスは、何らかの方法で公開しない限り、他のフォームからは「見えません」。

より技術的に言えば、ここで定義されているように、PicMover クラスは Application NameSpace のスコープに存在します。これは、アプリケーション内の他のすべてのクラスがインスタンスを作成するために使用できるオブジェクトのタイプを作成するためのテンプレートですが、アプリケーション内のどのクラスもデフォルトで のインスタンスを「持っていません」。

「注入」を示すDeerchaoの優れた回答の代替案を次に示します。クラスのインスタンスに参照を「保持」させたい場合は、注入が適切です。この例では、PictureBoxのFormのインスタンスが「PicMover クラスのインスタンス:

Form1 の PictureBox への参照を保持するクラス 'PicMover 内でパブリック プロパティを宣言します。

public class picMover
{
    // note use of C# 3.0 automatic property feature here
    public PictureBox myPictureBox { get; set; }

    public void movePic(int distance)
    {
        // note test for null here
        if (myPictureBox != null)
        {
            myPictureBox.Left += distance;
        }
    }
}

Form1 では、'PicMover のインスタンスを作成した後、内部の PictureBox プロパティを設定し、内部の 'movePic メソッドを次のように使用します。

// instance of PicMover created in the Form's scope
picMover myPicMover = new picMover();

private void Form1_Load(object sender, EventArgs e)
{
    // when the Form loads inject the reference to the PictureBox instance into the instance of 'PicMover
    myPicMover.myPictureBox = pictureBox1;
}

private void button1_Click(object sender, EventArgs e)
{
    myPicMover.movePic(23);
}

私見ですが、オブジェクトへの「注入された」参照が存在することを確認するためにテストすることに注意してください。使用する前にnullをテストすることは、良い習慣です。

PictureBox オブジェクトのインスタンスを「PicMover」のインスタンスに「バインド」するもう 1 つの方法は、PictureBox のインスタンスをクラスのコンストラクターにパラメーターとして渡すことです。そのテクニックを示す回答をすでに投稿しているでしょう。内部参照が変更されると予想される場合は、PictureBox をクラスのコンストラクターに渡すのに対して、変更されると予想されない場合は、ここに示すようにパブリック プロパティを使用して "注入" することをお勧めします。

もう 1 つの戦略は、'PicMover を public static メソッドを使用して public static クラスにすることです。これにより、すべての Form が「それを見る」ことができ、どのフォームもそのインスタンスを作成する必要がなくなります (実際、フォームを「インスタンス化」することはできません)。したい場合は静的クラス:それが静的クラスです)。

于 2009-12-22T02:51:53.527 に答える