教程书中的 C# 新手问题:“Head Start C# Greyhound Lab”
我是 C# 的新手,但我一直在慢慢阅读 Head Start C# 教程书(到目前为止,我发现它非常有趣)。然而,我在第一个“实验室”作业中遇到了困难:他们提供了用于控制 PictureBox 的代码,我可以让该代码在主窗体上工作,但我无法让它在类中工作。我已经回顾了旧的课程,并且对我所缺少的内容有了相当好的了解,但是对于我的一生,我无法弄清楚如何从我的班级中访问主窗体的 PictureBox (正如教程告诉我我应该做的那样)。
这有点令人沮丧,因为我根本没有在书中跳到前面,但我发誓我们还没有涵盖这一点。无论如何,对真正的程序员有吸引力。
以下是教程中名为“您的对象可以控制表单上的内容”的部分中提供的代码(对于任何读过这本书的人来说,请参阅第 208 页)。
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.
*/
}
}
}
I'm an extreme newbie at C#, but I've been slowly moving through the Head Start C# tutorial book (and finding it extremely enjoyable so far). However, I've hit a wall on the first "lab" assignment: They give code for controlling a PictureBox, and I can get that code to work on the main Form, but I can't get it to work from within a Class. I've gone back over the old lessons, and I've got a fairly good idea of what I'm missing, but for the life of me I can't figure out how to access the main Form's PictureBox from within my class (as the tutorial is telling me I should do).
It's a bit frustrating, because I didn't jump ahead in the book at all, but I'd swear we haven't covered this yet. Anyway, appealing to Real programmers.
Here's the code provided in the tutorial, in a section called "Your object can control things on your form" (p208 for anyone with the book).
Point p = MyPictureBox.Location
p.x += distance;
MyPictureBox.Location = p
Below I'm posting the relevant (I think?) parts of my code below. Button1 works for me when compiled, Button2 "works," in the sense that the current class just tells it to print the passed INT because I've commented out the code I can't get to work.
Thanks in advance!
Code for the 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
}
}
}
Code for the PicMover class:
//
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.
*/
}
}
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
如果您需要访问某些内容,为什么不直接授予它访问权限呢?就像将它作为参数传递给方法一样。
现在在button2点击事件处理程序中:
If you need to access something, why don't you just give it access? Like passing it as a argument to the method.
now in button2 click event handler:
教程代码看起来像是您从类 (MyPictureBox.Location) 中获取位置,然后更改位置,然后将对象移动到新位置。
第二个按钮按下事件是不同的。也许您应该从函数返回一个位置?因此,当您调用该函数时,您将主窗体上的 PictureBox 设置为返回的值。
The tutorial code LOOKS like you are grabbing the location from your class (MyPictureBox.Location) then changing the location, then moving your object to that new location.
The second button press event is different. Perhaps you should be returning a location from the function? So, when you call the function, you set the PictureBox on the main form to the value returned.
如果您想创建一个可以从任何 Form 访问的通用类...创建它的实例...以移动该 Form 上的任何 PictureBox,那么“Deerchao 的答案会告诉您”怎么做。
尽管...考虑...每个表单都将声明自己的 PicMover 实例; Form1 的 PicMover 实例对任何其他 Form 都是“不可见的”,除非您也以某种方式发布它。
从技术角度来说:这里定义的 PicMover 类存在于应用程序命名空间的范围内;它是一个用于创建对象类型的模板,应用程序中的每个其他类都可以使用该对象类型来创建其实例,但默认情况下,应用程序中没有一个类“拥有”实例。
这是 Deerchao 的优秀答案的一个替代方案,演示了“注入”:当您希望类的实例“保留”引用时,注入是合适的:在这个例子中,我们说窗体的 PictureBox 实例“绑定”到'PicMover 类的实例:
我们在类 'PicMover 中声明一个公共属性,它将保存对 Form1 的 PictureBox 的引用:
因此,在创建 'PicMover 的实例后,在 Form1 中,设置其内部 PictureBox 属性,然后使用其内部'movePic 方法:像这样:
请注意,恕我直言,通过在使用之前测试 null 来测试以确保对对象的“注入”引用存在,这是一个好习惯。
您可以将 PictureBox 对象的实例“绑定”到 'PicMover 的实例中的另一种方法是将 PictureBox 的实例作为参数传递给该类的构造函数:我敢打赌,当我完成发布此内容时,其他人将已经发布了一个显示该技术的答案。当您期望内部引用发生更改时,您可能希望使用公共属性“注入”,如下所示,而当您不希望它发生更改时,则将 PictureBox 传递给类的构造函数。
另一种策略是使“PicMover”成为一个具有公共静态方法的公共静态类:然后每个表单都可以“看到它”,并且不需要任何表单来创建它的实例(事实上,您不能“实例化”静态类(如果您愿意):这就是静态类)。
If you want to create a general purpose class that can be accessed from any Form ... that creates an instance of it ... to move any PictureBox on that Form, then 'Deerchao's answer shows you how to do it.
Although ... consider ... every Form is going to have declare its own instance of PicMover; Form1's instance of PicMover is not "visible" to any other Form unless you also somehow publish it.
To put it more technically : the PicMover class, as defined here, exists in the Scope of the Application NameSpace; it's a template for creating type of object that every other Class in the Application can use to make an instance of, but that no Class in the Application "has" an instance of by default.
Here's an alternative to Deerchao's excellent answer that demonstrates "injection" : injection is appropriate when you want an instance of a class to "hold onto" a reference : in this example we say that the Form's instance of a PictureBox gets "bound" to an instance of the 'PicMover class :
We declare a Public Property within the class 'PicMover that will hold a reference to Form1's PictureBox :
So in Form1 after you create the instance of 'PicMover, you set its internal PictureBox Property, and then use its internal 'movePic method : like this :
Note that, imho, testing to make sure an "injected" reference to an object exists, by testing for null before using it is a good habit to get into.
Another way you can get an instance of the PictureBox object "bound" into an instance of 'PicMover is to pass the instance of the PictureBox to the Constructor of the class as a parameter : I bet by the time I finish posting this, someone else will have already posted an answer showing that technique. You might want to "inject" using a Public Property as shown here when you expect the internal reference to be changed vs. passing the PictureBox in to the Constructor of the Class when you don't expect it to be changed.
Another strategy is to make 'PicMover a public static class, with public static methods : then every Form can "see it," and there's no need for any form to make an instance of it (in fact you can't "instance" a static class if you wanted to : that's what a static class is).