فتح نموذج آخر في ج. فتح نموذج ثاني وتمرير البيانات إلى النموذج الرئيسي

يشترك
انضم إلى مجتمع "shango.ru"!
في تواصل مع:

أريد اليوم أن أتحدث عن كيفية إنشاء مشروع Windows Forms في لغة C++ في Visual Studio 2013 IDE والحقيقة هي أنه، بدءًا من VS 2012، تمت إزالة عنصر تطبيق Windows Forms من قائمة المشاريع التي يمكن إنشاؤها. الآن أنا أتحدث عن المشروع الموجود في لغة C++؛ يمكنك إنشاء مثل هذا المشروع في لغة C# عن طريق تحديد العنصر المناسب في القسم الخاص بالمشاريع التي تم إنشاؤها. ومع ذلك، فإن حقيقة عدم إمكانية اختيار مثل هذا المشروع من القائمة لا تعني أنه لا يمكنك إنشائه بنفسك. وهذا هو بالضبط ما أريد أن أتحدث عنه في هذه المقالة.

أول ما عليك فعله هو تشغيل Visual Studio. بمجرد تشغيل VS، انقر فوق ملف > جديد > مشروع

بعد ذلك، ستفتح لك نافذة تطلب منك تحديد نوع المشروع. نحتاج إلى تحديد القسم الفرعي CLR في قسم Visual C++ وتحديد مشروع CLR فارغ.

عند إنشاء المشروع، في Solution Explorer، انقر بزر الماوس الأيمن فوق المشروع الذي تم إنشاؤه. في قائمة السياق التي تفتح، حدد إضافة > إنشاء عنصر وفي القائمة التي تفتح، في قسم واجهة المستخدم، حدد نماذج Windows

بمجرد إضافة النموذج، حدد الملف MyForm.cpp في Solution Explorer. سيتم فتح علامة تبويب جديدة أمامك تحتوي على سطر واحد من التعليمات البرمجية:

#تشمل "MyForm.h"

نحتاج إلى إضافة الكود التالي إلى هذا الملف:

باستخدام نظام مساحة الاسم؛ باستخدام مساحة الاسم System::Windows::Forms; الفراغ الرئيسي(array ^ args) ( Application::EnableVisualStyles(); Application::SetCompatibleTextRenderingDefault(false); نموذج Project1::MyForm; Application::Run(%form); )

بعد ذلك في خصائص المشروع. حدد قسمًا فرعيًا نظامرابط القسم وفي سطر النظام الفرعي من القائمة المنسدلة، حدد Windows (/ SUBSYSTEM: WINDOWS) وانقر فوق "تطبيق".

دون إغلاق نافذة خصائص المشروع، انتقل إلى القسم الفرعي المتقدم وفي السطر نقطة الدخولنحن نكتب رئيسيومن ثم اضغط على المفتاح نعم.
هذا يكمل إعدادات المشروع. لتحرير مظهر النموذج، يتعين عليك الانتقال إلى علامة التبويب MyForm.h [المصمم] بالنقر المزدوج فوق ملف MyForm.h في Solution Explorer.

على الرغم من أن رأيي حول Visual Studio من Microsoft لا يزال كما هو، إلا أنه في بعض الأحيان يتعين عليك القيام بشيء ما بشأنه. إذا تعاملنا مع حقيقة أننا نكتب، في الواقع، ليس بلغة C++، ولكن بما يسمى C++/CLI، فإن العمل مع المكونات المرئية المألوفة لن يكون مختلفًا تمامًا عن نفس بيئات Borland. ولكن يمكن أن يخلق مشاكل، مقارنة بـ Builder، فلنفكر في 3 حالات نموذجية للعمل مع تطبيق يحتوي على أكثر من نموذج واحد. بيئة المثال مجانية لـ Visual C++ 2010 Express، ومن المفترض أن يكون للنموذج الرئيسي الاسم الافتراضي Form1.

مثال على إنشاء نموذج واستدعاءه برمجياً

يمكن تنفيذ هذا الرمز، على سبيل المثال، عن طريق النقر فوق زر في النموذج الرئيسي Form1.

Form^form2 = gcnew Form(); Button^ Button2 = gcnew Button(); Button2->Text = L"OK"; Button2->الموقع = النقطة(10,10); form2->Text = L"نافذتي"; form2->HelpButton = true; form2->FormBorderStyle = System::Windows::Forms::FormBorderStyle::FixedDialog; form2->StartPosition = FormStartPosition::CenterScreen; form2->Controls->Add(button2); form2->ShowDialog();

لإضافة معالج النقر لزر تم إنشاؤه برمجيًا، اكتب فقط قبل السطر الأخير من التعليمات البرمجية:

Button2->انقر على += gcnew System::EventHandler(this, &Form1::button2_Click);

قبل استدعاء الأسلوب form2->ShowDialog() أو form2->Show()؛

في هذه الحالة، رمز المعالج موجود في الوحدة النمطية الحالية Form1.h:

خاص: System::Void Button2_Click(System::Object^ sender, System::EventArgs^ e) (MessageBox::Show("هنا"); )

استدعاء نموذج آخر من النموذج الرئيسي

في القائمة، حدد المشروع - إضافة عنصر جديد - النموذج - الاسم Form2

دعونا نضيف عامل التشغيل

#تشمل "Form2.h"

قبل مساحة الاسم الأولى في Form1.h (أي، في بداية الملف).

لنقم بتضمين مؤشر لمثيل الفصل في القسم العام لفئة Form1:

نموذج 2 ^ F2؛

دعونا نضيف الكود الذي نحتاج إلى إنشاء النموذج الثاني فيه واستدعاءه:

F2=gcnewForm2(); F2->إظهار();

لحذف النموذج الثاني برمجياً، الكود التالي مناسب:

حذف F2؛

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

دعنا نصف البيانات الضرورية في فئة النموذج Form1 (هنا اسم ومساحة اسم مشروع Tabulator، إذا لزم الأمر، استبدلهما باسمك):

ثابت ثابت MAX_FORMS = 100؛ // الحد الأقصى لعدد النماذج int FormCount; // نموذج مصفوفة العداد ^F2؛ // مؤشر إلى مجموعة من النماذج

ثم نقوم بتهيئة البيانات باستخدام حدث التحميل للنموذج الرئيسي:

FormCount=0; F2 = مصفوفة gcnew (MAX_FORMS)؛

ثم سنقوم بتنفيذ الكود لإنشاء النموذج التالي

إذا (عدد النماذج يعرض()؛ ) else messageBox::Show("نماذج كثيرة جدًا!");

وإزالته:

إذا (FormCount) (حذف F2؛ FormCount--؛)

إذا أردنا إنشاء نماذج فرعية ليس بشكل منفصل، ولكن داخل النموذج الأصلي، ففي خصائص Form1 نحتاج إلى الإشارة إلى أنه "سلف" (قم بتعيين خاصية IsMdiParent = true)، وقبل إظهار النموذج الفرعي باستخدام الأمر F2->إظهار () عامل التشغيل، ضع علامة عليه كنموذج فرعي 1:

F2->MdiParent = this;

استدعاء أسلوب النموذج الأصل من نموذج فرعي

لا يمكننا الاستغناء عن استخدام ملفات .cpp، وهذا ليس سيئًا - فكتابة التعليمات البرمجية في ملفات .h تؤدي عمومًا إلى تعطيل نظام C الصحيح :)

دعونا نصف العملية خطوة بخطوة.

1) هناك نموذجان - Form1 وForm2، في Form1 يوجد زر (الزر 1، سيفتح النموذج الثاني) والتسمية (التسمية 1، هنا سنقوم بتغيير النص). في Form2 - Button1، عند النقر عليه، سيتغير النص الموجود في التسمية 1.

2) بما أننا نحتاج إلى الوصول إلى الثاني من النموذج الأول، ومن الثاني إلى الأول، فستنشأ مشكلة الإسنادات الترافقية (عندما يشير Form1.h إلى Form2.h، والذي بدوره يشير مرة أخرى إلى Form1.h) . ولتفادي ذلك، سنقوم بنقل كود النموذج الأول (Form1)، الذي سيكون له حق الوصول إلى النموذج الثاني (Form2)، من ملف .h إلى ملف .cpp. وبالتالي، تحتاج إلى إنشاء ملف Form1.cpp.

3) قم بتعريف طريقة Set العامة في Form1.h بحيث يمكنك تغيير نص التسمية 1 (يمكن كتابة الكود في نهاية الملف، بعد #pragma endregion):

عام: مجموعة باطلة (سلسلة ^ نص) (label1->Text = text;)

4) في الملف Form2.h نقوم بتضمين Form1.h (في البداية):

#تتضمن "Form1.h"

وقم بإنشاء مُنشئ يقبل ويحفظ رابط النموذج الأول لمزيد من الاستخدام:

Form2(Form1^parent) (InitializeComponent();parentForm =parent;) // يمكنك كتابة الرابط أدناه مباشرة: public: Form1^parentForm;

5) عند النقر فوق الزر في Form2، سوف نقوم باستدعاء الطريقة Set للنموذج الأصلي:

خاص: النظام::Void Button1_Click(System::Object^ sender, System::EventArgs^ e) (parentForm->Set("hello from form2");parentForm->Show(); this->Hide(); )

6) يبقى فتح النموذج الثاني في النموذج الأول. للقيام بذلك، نقوم بنقل معالج النقر على الزر من Form1.h إلى Form1.cpp، وفي ملف .h نترك الإعلان الخاص به فقط.

من المرجح أن يتعلق السؤال المطروح في هذه المقالة بموضوع بناء بنية التطبيق، وليس بالمشكلة قيد النظر على وجه التحديد. إن نقل البيانات من نموذج إلى آخر ليس بالأمر الصعب على الإطلاق. للقيام بذلك، يكفي جعل عنصر التحكم الذي نريد الحصول على بياناته مفتوحًا، أي وضع علامة عليه باستخدام المعدل العام. أيضا، هناك خيار آخر ممكن. على سبيل المثال، في النموذج الأول نقوم بإنشاء كائن من النموذج الثاني عن طريق تمرير مرجع لأنفسنا إلى المنشئ، أي عن طريق تمرير مرجع إلى الأول من النموذج الأول إلى الثاني
SecondForm SecondForm = new SecondForm(this);
بطبيعة الحال، قبل القيام بذلك، يجب عليك الاهتمام بإنشاء حمل زائد لمنشئ النموذج الثاني.

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

الحل لهذه المشكلة بسيط للغاية. دعونا نلقي نظرة مباشرة على الكود. في المصمم، نقوم بإنشاء النموذج الرئيسي (سيتم تشغيله عند بدء تشغيل التطبيق). دعونا نضع واحدة مربع الكتابة, ملصقو زر.

بالضغط على الزر سيتم فتح النموذج الثاني وسيتم نقل النص من الحقل النصي للنموذج الرئيسي إلى الحقل النصي للنموذج الثاني. في البداية يكون الشكل الثاني كالتالي:

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

استخدام النظام؛ باستخدام System.Collections.Generic؛ باستخدام System.Linq؛ باستخدام System.Windows.Forms؛ مساحة الاسم From1FormTo2 ( برنامج فئة ثابتة ( // نقطة الإدخال الرئيسية للتطبيق. static void Main() ( Application.EnableVisualStyles(); Application.SetCompatibleTextRenderingDefault(false); Application.Run(new MainForm()); ) ) )

يبدو رمز النموذج الرئيسي كما يلي:

استخدام النظام؛ باستخدام System.Collections.Generic؛ باستخدام System.ComponentModel؛ باستخدام System.Data؛ باستخدام System.Drawing؛ باستخدام System.Linq؛ باستخدام System.Text؛ باستخدام System.Windows.Forms؛ مساحة الاسم From1FormTo2 (فئة عامة جزئية MainForm: النموذج ( // النموذج الثاني SecondForm SecondForm؛ // مُنشئ public MainForm() (InitializeComponent();) // معالج حدث نقل البيانات // من النموذج الرئيسي إلى النموذج الثاني الخاص void btn_mainForm_Click(object) المرسل، EventArgs e) ( SecondForm = new SecondForm(tb_mainForm.Text.Trim()); SecondForm.ShowDialog(); if ( SecondForm.DialogResult == DialogResult.OK) tb_mainForm.Text = SecondForm.ReturnData(); ) ) )

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

الآن الجزء الأكثر إثارة للاهتمام هو رمز النموذج الثاني:

استخدام النظام؛ باستخدام System.Collections.Generic؛ باستخدام System.ComponentModel؛ باستخدام System.Data؛ باستخدام System.Drawing؛ باستخدام System.Linq؛ باستخدام System.Text؛ باستخدام System.Windows.Forms؛ مساحة الاسم From1FormTo2 (فئة جزئية عامة SecondForm: النموذج ( // مُنشئ مثقل public SecondForm(string data) (InitializeComponent(); tb_ SecondForm.Text = data;) // معالج حدث نقل البيانات // من النموذج الثاني إلى النموذج الرئيسي باطل خاص btn_ SecondForm_Click (مرسل الكائن، EventArgs e) ( this.DialogResult = DialogResult.OK;) // طريقة عامة للوصول إلى // حقل النص في هذا النموذج سلسلة عامة ReturnData() ( return (tb_ SecondForm.Text.Trim()); ) ))

كما ترون، هناك تحميل زائد لمنشئ واحد يقبل نوع السلسلة. تذكر أننا نحاول نقل النص من TextBox. في المُنشئ، تمت جدولة المكونات لتتم تهيئتها وتعيين نص حقل النص على القيمة المرسلة من النموذج الأول. التالي، من خلال الاشتراك في هذا الحدث انقربالنسبة لزر النموذج الثاني، قمنا بإنشاء معالج btn_ SecondForm_Click، والذي يحاكي تشغيل الزر "موافق" في أي مربع حوار. وبذلك، وبالضغط على زر "إرسال" (من النموذج الثاني)، نقوم بتنفيذ الشرط

( SecondForm .DialogResult == DialogResult .OK)

النموذج الأول، لذلك، عن طريق استدعاء الأسلوب SecondForm .ReturnData()، قمنا بضبط الحقل النصي للنموذج الأول على قيمة الحقل النصي للنموذج الثاني.

أعتقد أن تشغيل هذه الطريقة لم يعد يتطلب شرحًا. فهو ببساطة يقوم بإرجاع النص من حقل نصي واحد، مع الحفاظ على خصوصيته.

ونتيجة لذلك قمنا بنقل البيانات إلى النموذج الثاني من الأول ومن الثاني إلى الأول دون الإخلال بمبادئ التغليف.

حاول إدخال النص "aaa" في حقل النص الخاص بالنموذج الأول والنقر فوق الزر. سترى هذا النص في حقل النص في النموذج الثاني الذي يفتح. حاول تغيير النص إلى "aaa ppp" وانقر على الزر. سترى كيف، بعد إغلاق النموذج الثاني، سيظهر هذا النص في حقل النص الخاص بالنموذج الرئيسي.

الآن، أعتقد أنك ستتمكن من نقل البيانات بين النماذج بشكل أكثر صحة. وفي المقالة التالية سنتحدث عن كيفية القيام بذلك في تطبيقات ASP.NET.

في بعض الأحيان يكون من الضروري الوصول إلى عناصر نموذج من نموذج آخر أثناء تنفيذ البرنامج. على سبيل المثال، يوجد نموذج Form1، نفتح منه Form2 آخر، والآن، أثناء العمل في Form2، نحتاج إلى الوصول إلى عناصر النموذج الأصلي Form1. لقد وجدت عدة طرق للقيام بذلك.

الطريقة الأولى. تمرير مرجع إلى متغير عام.

مساحة الاسم WindowsApplication1 (الفئة الجزئية العامة Form1: النموذج ( public Form1() (InitializeComponent();) زر الفراغ الخاص 1_Click(object sender, EventArgs e) ( Form2 frm = new Form2(); frm.but1 = this.button1; // إرسال رابط إلى الزر في النموذج Form2 frm.ShowDialog() ) ) ؛

في Form2، سيتوافق الآن المتغير الذي تم تمرير الارتباط إليه مع Button1 من Form1

مساحة الاسم WindowsApplication1 (فئة جزئية عامة Form2: Form (زر عام ولكن1؛ // سيحتوي هذا المتغير على رابط إلى زر1 من نموذج1 public Form2() (InitializeComponent();) زر باطلة خاصة1_Click(object sender, EventArgs e) (but1.Text = "اختبار" // تغيير النص الموجود على الزر 1 في النموذج 1 ) ) )

الطريقة الثانية. تمرير الرابط إلى النموذج الفرعي.

الجوهر هو نفسه تقريبًا في الطريقة الأولى. عند فتح Form2، نمرر فيه رابطًا للعنصر الذي نخطط لتغييره لاحقًا.

مساحة الاسم WindowsApplication1 (الفئة الجزئية العامة Form1: النموذج ( public Form1() (InitializeComponent();) زر الفراغ الخاص1_Click(object sender, EventArgs e) ( Form2 frm = new Form2(this.button1); // تمرير رابط إلى الزر إلى النموذج Form2 frm.ShowDialog() ) );

الآن في Form2 نحتاج إلى إنشاء متغير يحتوي على رابط لهذا الزر ومن خلاله سنصل إلى الزر الموجود في Form1 (السطور 5،7،9 و15).

مساحة الاسم WindowsApplication1 (فئة جزئية عامة Form2: Form (زر خاص ولكن1؛ // سيحتوي هذا المتغير على رابط للزر Button1 من النموذج Form1 public Form2(Button ولكن) // احصل على رابط للزر الموجود في المتغير لكن (but1) = لكن؛ // الآن سيكون ولكن 1 رابطًا للزر Button1InitializeComponent();) زر الفراغ الخاص 1_Click(object sender, EventArgs e) (but1.Text = "test"; // قم بتغيير النص الموجود على الزر Button1 في Form1 ) ) )

الطريقة الثالثة. الوصول إلى نموذج الوالدين بأكمله.

للقيام بذلك، تحتاج إلى إجراء تغييرات في عدة ملفات، ولكن في نفس الوقت سيكون لدينا إمكانية الوصول إلى جميع عناصر النموذج الأصلي ولا نحتاج إلى تمرير رابط لكل عنصر، كما في الطريقة الأولى.

الخطوة 1.في الملف Program.csقم بإنشاء متغير عام f1 (السطر 5).

مساحة الاسم WindowsApplication1 ( برنامج فئة ثابتة ( public static Form1 f1; // متغير سيحتوي على رابط للنموذج Form1 static void Main() ( Application.EnableVisualStyles(); Application.SetCompatibleTextRenderingDefault(false); Application.Run(new Form1( ) ) ))

الخطوة 2.افتتاح Form1.Designer.csوفيه، بالنسبة للعناصر التي يجب الوصول إليها من نموذج آخر، نتغير خاصعلى عام. على سبيل المثال، لنجعل Button1 في Form1 متاحًا للتغييرات.

النظام العام.Windows.Forms.Button Button1؛ // تم استبدال الخاص بالعامة

الخطوه 3. عند إنشاء Form1، نقوم بتعيين المتغير f1 رابطًا لهذا النموذج (السطر 7)

Namespace WindowsApplication1 (فئة جزئية عامة Form1: Form ( public Form1() ( Program.f1 = this; // الآن f1 سيكون رابطًا للنموذج Form1InitializeComponent(); ) زر باطلة خاصة1_Click(object sender, EventArgs e) ( Form2 frm = new Form2(); frm.ShowDialog();

الخطوة 4.الآن من أي نموذج أو من أي فئة يمكنك الوصول إلى عنصر Button1 الموجود في Form1 مثل هذا: Program.f1.button1. على سبيل المثال، اسمح للزر الموجود في Form2 بتغيير نص الزر الموجود في Form1:

مساحة الاسم WindowsApplication1 (الفئة الجزئية العامة Form2: النموذج ( public Form2() (InitializeComponent();) زر الفراغ الخاص 1_Click(object sender, EventArgs e) ( Program.f1.button1.Text = "test"; // تغيير النص الموجود على زر النموذج Form1 ) ) )



يعود

×
انضم إلى مجتمع "shango.ru"!
في تواصل مع:
أنا مشترك بالفعل في مجتمع "shango.ru".