کار با فرم های MDI
MDI یا Multiple Document Interface، نوعی طراحی رابط گرافیکی چند سندی است که، در آن کاربر قادر است، از چند فرم (فرزند) در داخل یک فرم (پدر) استفاده کند. مثالی از یک رابط چند سندی، نرم افزار مایکروسافت Word یا Excel هست. وقتی Excel رو اجرا میکنید یک پنجره والد ظاهر میشود که در این پنجره پدر میتوانید هر تعداد سند بعنوان پنجرههای فرزند ظاهر میگردند را باز کنید.
در یک برنامه MDI، تمام پنجرههای فرزند از یک نوار ابزار و یا نوار منو که در پنجره والد ظاهر میگردد، بصورت مشترک استفاده میکنند. یک از محدودیتهای پنجرههای فرزند اینست که، میتوانند تنها در محدودههای پنجره والد وجود داشته باشند. اجازه دهید که نحوه کار با فرمهای چند سندی را با یک مثال توضیح دهیم. یک برنامه ویندوزی ایجاد کرده و نام آن را MDIFroms بگذارید. بعد از بالا آمدن برنامه خاصیت IsMdiContainer فرم را به true تغییر میدهید. مشاهده میکنید که رنگ پس زمینه فرم به رنگ طوسی پر رنگ در میآید :
با این کار فرم پدر ایجاد میشود. حال نوبت به اضافه کردن فرم فرزند میرسد. برای اضافه کردن فرم دوم یا فرم فرزند به برنامه به صورت زیر عمل میکنیم :
نام فرم را هم در حالت پیشفرض رها کرده و دکمه add را میزنیم :
همانطور که در شکل زیر مشاهده میکنید، یک فرم به نام Form2 به برنامه اضافه میشود :
حال یک منو با استفاده از کنترل MenuStrip به فرم اول یا From1 و چند زیر منو هم به منو اضافه میکنیم :
حال بر روی زیر منوی Show Form1 دوبار کلیک کرده و کد زیر را در رویداد کلیک آن مینویسیم :
private void showForm2ToolStripMenuItem_Click(object sender, EventArgs e) { Form2 frm2 = new Form2(); frm2.Show(); frm2.MdiParent = this; }
به کلمه کلیدی this در کد بالا توجه کنید. چون این کلمه را در داخل فرم اول نوشتهایم در نتیجه به همین فرم اشاره میکند. و معنای آن این است که فرم والد frm2 همین فرم است. برنامه را اجرا کرده و بر روی زیر منوی Show Form2 کلیک کنید :
همانطور که در شکل بالا مشاهده میکنید، فرم دوم در داخل فرم اول نمایش داده و نسبت به گوشه بالا سمت چپ تراز میشود. اگر دوباره بر روی گزینه Show Form2 مشاهده میکنید که یک بار دیگر فرم دوم در داخل فرم اول به نمایش در میآید، برای جلوگیری از این کار میتوانید کد بالا را به صورت زیر تغییر دهید :
private void showForm2ToolStripMenuItem_Click(object sender, EventArgs e) { foreach (Form form in Application.OpenForms) { if (form.GetType() == typeof(Form2)) { form.Activate(); return; } } Form2 frm2 = new Form2(); frm2.Show(); frm2.MdiParent = this; }
حال اگر بخواهید فرم دوم در وسط فرم اول نمایش داده شود میتوانید کد زیر را هم به انتهای کدهای بالا اضافه کنید :
frm2.StartPosition = FormStartPosition.CenterScreen;
البته به جای CenterScreen میتوان مقادیر CenterParent، Manual، WindowsDefaultBounds و WindowsDefaultLocation را نوشت و نحوه عملکرد آنها را امتحان کرد. حال اگر بخواهید فرم فرزند کل فرم اول را در بر بگیرد و با تغییر سایز فرم پدر او نیز تغییر اندازه دهد باید از کد زیر استفاده کنید :
frm2.Dock = DockStyle.Fill;
حال برنامه را اجرا و نتیجه را مشاهده کنید :
البته این خط بالا را در برنامه فقط برای تست بنویسید و دوباره پاک کنید. اگر بخواهید از چند فرم در داخل فرم پدر استفاده کنید، وضع به همین منوال است. یک فرم دیگر به برنامه بالا و یک زیر منو هم به صورت زیر به منو اضافه کنید :
بر روی زیرمنوی جدید دوبار کلیک کرده و کدهای زیر را در داخل آن بنویسید :
private void showForm3ToolStripMenuItem_Click(object sender, EventArgs e) { Form3 frm3 = new Form3(); frm3.StartPosition = FormStartPosition.CenterScreen; frm3.Show(); frm3.MdiParent = this; }
برنامه را اجرا و هر دو فرم را باز کنید :
مشاهده میکنید که هر دو فرم بر روی هم قرار میگیرند چون خاصیت StartPosition بر روی CenterScreen است. حال اگر بخواهید آنها را به صورت مرتبتری در داخل فرم اول نمایش دهید باید چکار کنید؟ یک منوی با چند زیر منوی دیگر به فرم اضافه کنید :
به ترتیب بر روی زیر منوهای بالا کلیک کرده و کدهای زیر را در داخل آنها بنویسید :
private void cascadeToolStripMenuItem_Click(object sender, EventArgs e) { LayoutMdi(MdiLayout.Cascade); } private void tileHorizontalToolStripMenuItem_Click(object sender, EventArgs e) { LayoutMdi(MdiLayout.TileHorizontal); } private void tileVerticalToolStripMenuItem_Click(object sender, EventArgs e) { LayoutMdi(MdiLayout.TileVertical); } private void arrangeIconToolStripMenuItem_Click(object sender, EventArgs e) { LayoutMdi(MdiLayout.ArrangeIcons); }
اجرای برنامه و کلیک بر روی زیر منوهای بالا به صورت زیر است :
Cascade
Horizontal
Vertical
به این نکته توجه کنید که گزینه Arrange icon فقط در صورتیکه فرمهای فرزند Minimize باشند کار میکند. به این صورت که اگر فرمها را Minimize کرده و ترتیب آنها را بر هم بزنید این گزینه آنها را مرتب میکند :
سلام
من سه فرم دارم که یکی فرم اصلی هست MainForm
دومی Items /محصولات هست.
سومی new Item/ محصول جدید هست
دکمه ی محصول جدید در فرم محصولات هست و frm2.MdiParent = this; برای من کار نمیکنه
میخوام فرم محصول جدید از داخل فرم محصولات باز بشه ولی پارنتش فرم اصلی باشه. کدشو چطوری بنویسم؟
ممنون میشم اگه راهنمایی کنید.
سلام و خدا قوت ، سوالی داشتم ممنون میشم کمکم کنید
من یک فرم ایجاد کردم و داخل اون یک combobox قراردادم و داخلش چندتا گزینه تعریف کردم
در پایینش چندتا panel تعریف کردم که روی هم قرارشون دادم و خاصیت visible اونها رو false گذاشتم . بعد داخل رخداد selectitemchange مربوط به combobox با استفاده از دستور switch case نوشتم که هر کدوم از گزینه های combobox رو که انتخاب کردیم یکی از panel ها خاصیت visible ش به true تغییر پیدا کنه .
البته داخل هر بلوک case اول خاصیت visible بقیه panel ها رو false میکنم بعد اون panel مورد نظر رو true میکنم . متاسفانه بعضی از گزینه های combobox رو که میزنم عمل نمیکنه و فقط دو تاشون درست کار میکنه . لطفا کمکم میکنید؟
البته اگه برای این کار پیشنهاد دیگه ای هم دارید ممنون میشم بشنوم .
سلام، ممنون میشم همین سوالتون رو کپی و تو بخش پرسش و پاسخ مطرح بفرمایید
سلام من یه مشکل داشتم می خواستم ببینم اگه توی کد namespace WindowsFormApplication نتونستم به جای windowsformapplication چیز دیگه ای بنویسم و خطا داد اگه من تغییرش ندم مشکلی نیست چون توی مبحث treeview این کارو انجام دادم درست شد و اگه راهی داره که درستشه لطفا راهنمایی کنید و یه سوال دیگه ای که داشتم این بود که من توی قسمت دیدگاه هر مبحث رو که میخونم بعضی وقتها برای راهنمایی لینکهایی رو قرار دادید می خواستم بدونم جایی هست که همه ی اینها رو قرار داده باشید چون مطالب خوب و مفیدی مثل بقیه ی مطالبی که گذاشتین دارن ممنون میشم منو راهنمایی کنید
سلام دوست عزیز
ممنون میشم سوال تکراری نپرسین. شما قبلا اینو مطرح کردین، هم تو قسمت tree view و هم تو بخش پرسش و پاسخ جواب دادم. عرض کردم که شما وقتی یک پروژه ایجاد می کنید، یک namespace به نام اون پروژه براتون ایجاد میشه. مثلا یک پروژه جدید ایجاد می کنید و اسمشو میذارین treeview. حالا موقعی میرین تو برنامه فضای نام به صورت زیر ایجاد میشه
جوابی که بنده تو لینک زیر دادم رو هم نگاه کنید:
http://www.w3-farsi.com/forum
در ضمن شما چه کاری به فضای نام دارین؟
در مورد سوال دومتون هم عرض شود که بعضیاشون که لازم بودن رو تو کتاب سی شارپ نوشتم و بقیه هم تو سایت به صورت دسته بندی هستن
سلام من اینو انجام دادم ولی روی فرم parent ام یسری دکمه و تکست باکس دارم که میخوام فرم جدید جلوی همه اینا نمایش داده بشه. چجور باید انجام بدیم؟
سلام . با تشکر از زحمات شما
زمانی که یک فرم رو به عنوان فرم فرزند قرار میدم ، تغییراتی که تو دیتا گرید ویو فرم انجام میگرفت مثل رنگی شدن سلول های خاص دیتاگریدویو دیگه انجام نمیشه ،اما وقتی فرم به صورت تکی اجرا میشه کاملا درسته.
میخواستم بدونم این حالت فرزند گرفتن فرم باعث ایجاد تغییرات در نمایش فرم فرزند میشه؟
سلام
فرض کنید 3 تا فرم به نامهای f1 و f2 و f3 دارم.
میخواهم فرم f1 پدر همه فرمها باشد.
یک panel هم روی فرم f1 بصورت تمام صفحه قرار دادم.
فرم f2 میخوام فرزند فرم f1 باشد و روی panel فرم f1 بنمایش در آید.
داخل فرم f2 یک باتن است. هر وقت روی این باتن کلیک شد فرم f2 بسته شود و فرم f3 نمایش داده شود و فرزند فرم f1 شود.
چطور می توانم این کار را بکنم؟
لطفا راهنمایی کنید.
باتشکر
سلام، ممنون میشم سوالتونو تو بخش پرسش و پاسخ سایت مطرح بفرمایید
http://www.w3-farsi.com/forum
ممنون از این راهنمائی خوب شما
یه سوال دارم یه فرم طراحی کردم به عنوان فرم پدر بعد یه دکمه برای باز کردن یه فرم دیگه درست کردم ،فرم دومی رو به عنوان فرم فرزند معرفی نکردم ،کدی هست که با کلیک کردن روی فرم دومی اون رو به فرم فرزند تبدیل بکنه ،ممنون میشم اگه کمک کنید
خیلی خوب بود ممنون
خواهش می کنم، لطف دارین
سلام
من هرکاری می کنم کد frm3.MdiParent = this; ارور میده.