来自教程书的C#新手问题:“Head Start C#Greyhound Lab”

时间:2009-12-22 01:46:33

标签: c# class private public

我是C#的极端新手,但我一直在慢慢阅读Head Start C#教程书(到目前为止发现它非常有趣)。但是,我在第一个“实验室”任务中遇到了障碍:他们提供了控制PictureBox的代码,我可以让代码在主窗体上工作,但我不能让它在一个类中工作。我已经回过头来学习旧课程了,而且我已经很清楚我所缺少的东西,但对于我的生活,我无法弄清楚如何从我的班级中访问主要Form的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.
        */


    }
}

}

3 个答案:

答案 0 :(得分: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
}

答案 1 :(得分:0)

教程代码LOOKS就像你从类中获取位置(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

第二次按下按钮事件不同。也许你应该从函数返回一个位置?因此,当您调用该函数时,将主窗体上的PictureBox设置为返回的值。

答案 2 :(得分:0)

如果你想创建一个可以从任何Form访问的通用类...创建它的实例...在那个F orm上移动任何PictureBox,那么'Deerchao's答案告诉你如何做到这一点。

虽然......考虑...... 每个Form都会声明自己的PicMover实例;除非您以某种方式发布它,否则Form1的PicMover实例不会对任何其他表单“可见”。

更具技术性:此处定义的PicMover类存在于应用程序名称空间的范围内;它是一个用于创建对象类型的模板,应用程序中的每个其他类都可以用它来创建实例,但是应用程序中的任何类都没有的实例默认

这里是Deerchao的优秀答案的替代品,它演示了“注入”:当你想要一个类的实例“保持”一个引用时,注入是合适的:在这个例子中我们说Form的一个PictureBox的实例得到了“绑定” “到'PicMover类的实例:

我们在类'PicMover中声明了一个公共属性,它将保存对Form1的PictureBox的引用:

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;
        }
    }
}

因此,在创建'PicMover实例后,在Form1中,设置其内部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);
}

请注意,imho,测试以确保对象的“注入”引用存在,通过在使用它之前测试null是一个很好的习惯。

另一种可以将PictureBox对象的实例“绑定”到'PicMover实例中的方法是将PictureBox的实例作为参数传递给类的构造函数:我在完成发布时将其打赌,其他人已经发布了一个显示该技术的答案。当您希望更改内部引用时,可能需要使用公共属性“注入”,而不希望更改时将PictureBox传递给类的构造函数。

另一种策略是使用公共静态方法使'PicMover成为公共静态类:然后每个表单都可以“看到它”,并且不需要任何表单来构建它的实例(实际上你不能“实例“如果你想要一个静态类:那就是静态类。”