C# سؤال جديد من كتاب البرنامج التعليمي: "Head Start C# Greyhound Lab"

StackOverflow https://stackoverflow.com/questions/1943744

  •  20-09-2019
  •  | 
  •  

سؤال

أنا مبتدئ متطرف في C# ، لكنني كنت أتنقل ببطء عبر كتاب Head Start C# (وأجدته ممتعًا للغاية حتى الآن). ومع ذلك ، لقد ضربت جدارًا في مهمة "Lab" الأولى: إنها تعطي رمزًا للتحكم في صندوق صور ، ويمكنني أن أعمل هذا الرمز على النموذج الرئيسي ، لكن لا يمكنني تشغيله من داخل الفصل . لقد عدت إلى الدروس القديمة ، ولدي فكرة جيدة إلى حد ما عما أفتقده ، لكن من أجل حياة لي ، لا يمكنني معرفة كيفية الوصول إلى صندوق صور النموذج الرئيسي من داخل صفي ( كما يخبرني البرنامج التعليمي أنني يجب أن أفعل).

إنه أمر محبط بعض الشيء ، لأنني لم أقفز في الكتاب على الإطلاق ، لكنني أقسم أننا لم نغطي هذا بعد. على أي حال ، جذب المبرمجين الحقيقيين.

إليك الرمز المقدم في البرنامج التعليمي ، في قسم يسمى "يمكن للكائن التحكم في الأشياء في النموذج الخاص بك" (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.
        */


    }
}

}

هل كانت مفيدة؟

المحلول

إذا كنت بحاجة إلى الوصول إلى شيء ما ، فلماذا لا تتيح الوصول إليه؟ مثل تمريرها كوسيطة إلى الطريقة.

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
}

نصائح أخرى

يبدو أن رمز البرنامج التعليمي هو أنك تستحوذ على الموقع من الفصل (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 على النموذج الرئيسي على القيمة التي تم إرجاعها.

إذا كنت تريد إنشاء فئة للأغراض العامة التي يمكن الوصول إليها من أي شكل ... تنشئ مثيلًا منه ... لنقل أي صندوق صور على ذلك وorm ، ثم "إجابة ديرتشاو توضح لك كيفية القيام بذلك.

على الرغم من ... النظر ... كل شكل من أشكال سيعلن مثاله الخاص من picmover; ؛ إن مثيل Picmover الخاص بـ Form1 ليس "مرئيًا" لأي نموذج آخر إلا إذا قمت أيضًا بنشره بطريقة ما.

لوضعها أكثر تقنيًا: يوجد فئة Picmover ، كما هو محدد هنا ، في نطاق مساحة اسم التطبيق ؛ إنه قالب لإنشاء نوع من الكائنات التي يمكن أن تستخدمها كل فئة أخرى في التطبيق لعمل مثيل ، ولكن لا يوجد فئة في التطبيق "لها مثيل بشكل افتراضي.

فيما يلي بديل عن إجابة ديرتشاو الممتازة التي توضح "الحقن": الحقن مناسب عندما تريد مثيلًا للفصل "التمسك بـ" مرجع: في هذا المثال ، نقول أن مثيل النموذج الخاص بـ "مربع الصورة" ملزم بـ " مثال على "فئة Picmover":

نعلن عن خاصية عامة داخل picmover "الفصل" الذي سيحتفظ بإشارة إلى مربع صور Form1:

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

لاحظ أنه ، IMHO ، الاختبار للتأكد من وجود إشارة "حقن" إلى كائن ، من خلال اختبار NULL قبل استخدامه ، يعد عادةً عادة للدخول.

هناك طريقة أخرى يمكنك الحصول على مثيل لكائن Picturebox "ملزم" في مثيل من "picmover سيكون قد نشرت بالفعل إجابة تبين هذه التقنية. قد ترغب في "حقن" استخدام خاصية عامة كما هو موضح هنا عندما تتوقع تغيير المرجع الداخلي مقابل تمرير صندوق الصورة إلى مُنشئ الفصل عندما لا تتوقع تغييره.

تتمثل الإستراتيجية الأخرى في جعل "picmover" فئة ثابتة عامة ، مع طرق ثابتة عامة: ثم يمكن لكل شكل "رؤيته" ، وليس هناك حاجة لأي شكل لعمل مثيل منه (في الواقع لا يمكنك "مثيل" فئة ثابتة إذا كنت تريد ذلك: هذا ما هو فئة ثابتة).

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top