PDA

View Full Version : سوال: بستن فرم اول و نمایش فرم دوم!



kh1387
سه شنبه 30 مهر 1387, 20:43 عصر
با سلام
اینهمه بر نامه نویس هنوز کسی نتونسته راهی پیدا کنه که وقتی فرم دوم بالا اومد فرم اول بسته شه؟
مدیران سایت خواهشا اگه می دونید راهنمایی کنید.
جناب Sinpin خواهشا راهنمایی کنید
متشکرم

Armin060
سه شنبه 30 مهر 1387, 20:47 عصر
اين كه كاری نداره...!!!
خوب تو رويداد load فورم دو تعريف كن كه فورم يك بسته بشه..!!

reza6384
سه شنبه 30 مهر 1387, 20:52 عصر
دوست عزیز سوالتون خیلی ساده به نظر میاد. شاید منظورتون رو دقیق متوجه نشدم. خوب بعد از Form2_load بزن Form1.Close و در قسمت Properties پروژه تنظیم کن که وقتی application تموم بشه که آخرین فرم بسته شه.

Armin060
سه شنبه 30 مهر 1387, 21:16 عصر
از طريق روشی كه شما گفتيد نميشه....!!!! ( reza6384 (http://barnamenevis.org/forum/member.php?u=50189) )

kh1387
سه شنبه 30 مهر 1387, 22:07 عصر
اين كه كاری نداره...!!!
خوب تو رويداد load فورم دو تعريف كن كه فورم يك بسته بشه..!!


لطفا اول امتحان کنید بعد پست بدید.
متشکر

kh1387
سه شنبه 30 مهر 1387, 22:11 عصر
دوست عزیز سوالتون خیلی ساده به نظر میاد. شاید منظورتون رو دقیق متوجه نشدم. خوب بعد از Form2_load بزن Form1.Close و در قسمت Properties پروژه تنظیم کن که وقتی application تموم بشه که آخرین فرم بسته شه.


ظاهراً معلومه کسی این روش رو امتحان نکرده. خب یه ذره توضیح می دم تا دوستان متوجه بشوند:
دوست عزیز اولا ما نمی تونیم در کلاس Form1 از متد Close استفاده کنیم.
ثانیا باید یک شیئ از فرم 1 new کنیم که این کار باعث میشه که همون فرم نیو شده بسته شه نه فرم اصلی
موفق باشید

Armin060
سه شنبه 30 مهر 1387, 23:02 عصر
من زياد اين كار رو كردم. بگذريم.

كد اوليه در فورم يك بايد به صورت زير باشه :



public Form1()
{
InitializeComponent();
//Added to support default instance behavour in C#
if (defaultInstance == null)
defaultInstance = this;
}
#region Default Instance

private static Form1 defaultInstance;

/// <summary>
/// Added by the VB.Net to C# Converter to support default instance behavour in C#
/// </summary>
public static Form1 Default
{
get
{
if (defaultInstance == null)
{
defaultInstance = new Form1();
defaultInstance.FormClosed += new FormClosedEventHandler(defaultInstance_FormClosed) ;
}

return defaultInstance;
}
}

static void defaultInstance_FormClosed(object sender, FormClosedEventArgs e)
{
defaultInstance = null;
}

#endregion
بعد در فورم دو بنويسيد كه :


Form1.Default.Close();

SMRAH1
چهارشنبه 01 آبان 1387, 09:04 صبح
سلام

برای بستن یک فرم دیگر مثلا با عنوان Form1_1 کافیه دستور زیر را (در هرجای برنامه) به کار برید:

foreach (Form f in Application.OpenForms)
{
if(f.Text == "Form1_1")
f.Close();
}
البته حتما باید به یک نکته توجه کنید.اگر فرمی که می خواهید بسته شود،فرم اصلی برنامه باشد(در تابع Main برنامه آنرا به متد Run شی Application فرستادید)،این عمل باعث بسته شدن برنامه می شود .در اینصروت راهکار هایی برای جلوگیری از این موضوع وجود دارد که در جای خود باید بحث شود.

موفق باشید

h.jaza
چهارشنبه 01 آبان 1387, 09:49 صبح
جواب خیلی واضحه:
مثلا در رویداد کلیک یه باتن در فرم اول (که البته نباید فرم اصلی باشه) می نویسیم:



private void button1_Click(object sender, EventArgs e)
{
Form2 frm2 = new Form2();
frm2.Show();
this.Close();
}

همون طور که معلومه خیلی سادس. اما دو تا نکته ی مهم:

یک: ولی یه نکته ی خیلی ظریف در اون هست و اونم اینه که اگر فرم اول شما همون فرم اصلیه شما باشه، این کد باعث میشه تا پروژه کلا بسته بشه چرا که شما با دستور ;()this.Close میای و فرم اصلی رو می بندی، لذا به تبعش کل برنامه هم بسته میشه. اگر بخوام بهتر بگم، اگر شما به کلاس program نگاه کنید، این تابع رو می بینید:



static void Main()
{
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(fals e);
Application.Run(new Form1());
}

که همون طور که معلومه، در آخرین خطش فرم اصلیه شما رو صدا زده. حال اگر شما فرم اصلی رو ببندی، مثل هر تابع دیگه ای برمی گرده دوباره به ایجا و خط دستور بعد از این فراخوانی رو می خواد اجرا کنه که در واقع همون انتهای برنامس.

لذا اگر شما برای فرم اصلی، این کد رو بنویسی، این کار باعث بسته شدن کل پروژه خواهد شد. لذا باید در تعریف فرم اصلیتون دقت کنید. فرم اصلیه شما فرمی خواهد بود که تا آخرین لحظه ی وجود برنامه، حیات خواهد داشت.

دو: اگر توجه کرده باشید، در اینجا از متد Show و نه ShowDialog استفاده شده است؛ چرا که استفاده از ShowDialog باعث میشه تا زمانی که فرم ثانویه باز هستش، به فرم اولی دسترسی نداشته باشیم؛ در نتیجه کد ;()this.Close دیگر اجرا نمی شود تا باعث بسته شدن فرم اولی شود.

تمام

خیلی کتابی نوشتم، نی :لبخند:

kh1387
چهارشنبه 01 آبان 1387, 17:12 عصر
با سلام
خیلی خیلی از نظرات و توجه شما دوستان مهربان و قدرتمندم متشکرم.
اما همانطور که اشاره کردید، مسئله من همون فرم اوله...
وگرنه فرمهای دیگه هزار نوع بلا می شه سرشون اورد.
اگه کسی کلاسی فرمولی راه حلی در این زمینه داره ممنون می شم.
در ضمن من نمی خوام فرم اول رو Hide کنم.

h.jaza
چهارشنبه 01 آبان 1387, 17:35 عصر
دوست عزیز من فکر نمی کنم راه دیگه ای وجو داشته باشه.

به نظر من اصلا این اصولی نیست که شما فرم اصلی رو بخواین وسط برنامه ببندین. فرم اصلی همیشه پایدار ترین فرم هستش. لذا فکر می کنم شما باید فرم اصلیتون رو تغییر بدین.

kh1387
چهارشنبه 01 آبان 1387, 18:14 عصر
یعنی باید فقط اونرو hide کنم؟

Armin060
چهارشنبه 01 آبان 1387, 18:23 عصر
ببخشديد، ميشه بگيد واسه ی چی ميخوايد فورم اصلی رو ببنيد؟

h.jaza
چهارشنبه 01 آبان 1387, 18:42 عصر
من راه دیگه ای بلد نیستم.

از دوستان اگر راه دیگه بلد هستند، بگن.

با تشکر

SMRAH1
چهارشنبه 01 آبان 1387, 19:46 عصر
سلام

با اينکه معمولا گفته دوستمان جناب h.jaza صحيح است و 'اصولي نيست که شما فرم اصلي رو بخواين وسط برنامه ببندين. فرم اصلي هميشه پايدار ترين فرم هستش' ولي گاهي اوقات استثنائاتي هم موجودند.براي نمونه در اينجا (http://barnamenevis.org/forum/showpost.php?p=605332&postcount=150)(روش Instal3) از همين جمله اند (که روشي که در ادامه خواهد آمد،بکار رفته است).

اول از همه توجه شما را به متد Run شي Application جلب مي کنم.اين متد است که پايداري (حيات) برنامه را به يک شي ديگر گره مي زند.به طور پيشفرض اين شي فرم اول يا فرم اصلي برنامه است.ولي اگر بخواهيم اين حيات را مستقل از فرم بگيريم چه؟
براي اين منظور Run شي Application داراي دو پياده سازي متفاوت ديگر است (در مجموع سه پياده سازي).يک از آنها که معمولا استفاده مي شود (و بشکل پيشفرض ويژوال استوديو آن را ايجاد مي کند) حالتي است که يک شي فرم مي گيرد.ولي ما نياز به پياده سازي ديگري از اين متد که يک شي مشتق شده از ApplicationContext را دريافت مي کند.در واقع تا اين شي برپاست،برنامه حيات دارد.در اين حالت مهم نيست که چند فرم باز مي شود يا بسته،فقط تا هنگامي که اين شي حيات دارد و دستور

ExitThread();
از اين شي (که از ApplicationContext ارث برده شده است) فراخواني نشده است اين برنامه وجود دارد.

براي همين منظور :
1) بايد ابتدا يک شي از ApplicationContext مشتق کنيد.
2) يک نمونه از اين شي (اين شي را مي توانيد به شکل سينگلنون معرفي کنيد) را به Application.Run ارسال کنيد.
3) راه کاري براي خروج از اين برنامه در نظر داشته باشيد.توجه کنيد که اگر خروج از برنامه به شکل مناسب انجام نشود،برنامه همچنان ادامه مي يابد و در حافظه قرار دارد (حتي اگر نمود خارجي نداشته باشد).

نمونه 1 (در ضميمه) اين روش را توصيف مي کند.با پياده سازي کلاس MyApplicationContext که از ApplicationContext مشتق شده است و معرفي به Application.Run برنامه حتي بعد از بسته شدن فرم ها مي تواند ادامه حيات دهد.فرم 1 باز مي شود،سپس فرم دوم باز شده و فرم 1 را مي بندد. در نهايت با زدن دکمه Close Program در فرم 2،برنامه بسته مي شود.البته اين برنامه داراي يک ايراد مهم است. به دليل عدم توجه به نکته سوم بالا (خروج از برنامه به شکل مناسب)،چنانچه فرم اول يا دوم را با دکمه Close خوده فرمها ببنيد،برنامه همچنان در حافظه است ولي چيزي ديده نمي شود!!!!

براي فرار از اين نکته بايد فرآيند بستن برنامه را در هر فرم (بخصوص در Close فرم) مديريت کنيد.به همين منظور نمونه 2 تدارک ديده شده که تمام فرم ها از BaseForm مشتق شده اند تا به برنامه نويسي اين امکان داده شود که بدون درگيري در هر فرم،فقط با ارث بري فرم هاي خود از BaseForm بتواند به راحتي توجه خود را معطوف به فرم خود کند و اين فرم پايه،تمام فرآيند لازم براي بستن خودکار برنامه (در صورت بسته شدن تمام فرمها )،مديريت کند.البته در برنامه هاي پيچيده تر بايد نکات بيشتري لحاظ شد که به فراخور برنامه متفاوت است.

نکته 1 : در اين دو مثال باز هم ملاک فرم ها است ولي الزاما در يک برنامه براي استفاده از اين روش براي حيات برنامه ،نياز به فرم ها نيست.به همين منظور ديدن مثال MSDN را ،حتما،توصيه مي کنم

نکته 2: دستور

Application.ExitThread();
در هر برنامه،حيات برنامه را خاتمه مي دهد.توجه به اين نکته مهم است که اين متد برنامه را،بدون توجه به وضعيت آن و به شکل اجباري (به قول خودمون با زور:چشمک:) مي بندد.براي نمونه اگر در فرمي که در حال اجراست،اين دستور فراخواني شود،حتي رويداد هاي FormClosing و FormClosed آن فرم نيز تحريک نمي شود (حتي فرم ببيچاره نمي فهمد که کي نيست مي شود!!:گریه:).

موفق باشيد

SMRAH1
چهارشنبه 01 آبان 1387, 20:04 عصر
ببخشید دوباره فراموش کردم فایل ضمیمه رو بگذارم.

h.jaza
چهارشنبه 01 آبان 1387, 21:21 عصر
SMRAH1 (http://barnamenevis.org/forum/member.php?u=44567) جان خیلی خلیی ممنونم به خاطر این جواب خیلی مفید، جالب و کاربردیتون.

فقط یه سوال اول دبستانی:
فرق ;()Application.Exit با ;()Application.ExitThread چیه؟

بازم مرسی از جوابتون

SMRAH1
چهارشنبه 01 آبان 1387, 21:51 عصر
سلام

اول اینکه خواهش میکنم.دوم اینکه سئوالتون هم خیلی فنیه.سوم اینکه من خودم هم هنوز دارم میاموزم و قطعا جواب پخته ای نمی توانم بدهم و حتما هم پر از ایراد است.چهارم اینکه:

همانطور که می دونید،در ویندوز ،برنامه ها بر اساس پیغام (یا رویداد) استوارند.در واقع Application.Run یک حلقه پیغام ایجاد می کنه (Message Loop) که تا زمانی که لازم است ادامه پیدا می کنه.
به طور معمولی برنامه ها، با پیغام خاصی (در واقع همان پیغام WM_QUIT در win32) متوجه زمان خروج شده و اقدام به بسته شدن خودشون می کنند.متد Exit هم پیغام پایان رو ارسال می کنه و عملا بعد از Proccess این پیغام از Loop خارج می شود (مثلا رویداد ApplicationExit شی Application ارسال می شود و ..) ولی وقتی متد ExitThread فراخوانی می شود،عملا loop شکسته شده و برنامه به یکباره پایان می پذیرد (بدون ایجاد فرصت پایان دادن به برنامه در صورت نیاز).این مورد بیشتر برای برنامهایی است که بدرفتارند یعنی علیرغم درخواست سیستم عامل مبنی بر پایان،هنوز در حال کار هستند (فرایند ShotDown آنها طولانی شده است یا اصلا نمی خواهند پایان یابند !!!!)،در این حالت سیستم عامل عملا Thread آن را بسته و اجازه ادامه را از آنها سلب می کند.

اگر ابرادی در گفته های بنده هست،لطفا تصحیح بفرمایید

موفق باشید

masoudtbt
شنبه 04 آبان 1387, 15:20 عصر
سلام

با ایجاد یک متغیر static در Program.cs به راحتی می توان این کار را کرد

فایل ضمیمه

SMRAH1
شنبه 04 آبان 1387, 16:14 عصر
سلام

البته که راه های رسیدن به خدا متنوع است!
در ضمن در کد شما نیاز به بار کردن فرم دوم در button1_Click نیست!(همون Application.Run دوم فرم دوم رو بار می کنه)

موفق باشید

dokhtare7darya
جمعه 07 تیر 1392, 10:50 صبح
من مبتدی هیچی از این صحبت ها حالیم نشد،آخر سر مجبور شدم در program.cs برنامه ام،فرم لاگین رو فرم دوم قرار بدم و در form2_load :

LoginUser frm = new LoginUser();
frm.ShowDialog();


و بعدش در کد فرم لاگینم.بعد از شو کردن فرم اول مجبور به بستن فرم لاگین شدم که این در عمل باعث شد که من مجبور شم 2 بار هر کدووم رو ببندم که فرم هام بسته شن

hassan181
سه شنبه 20 آبان 1393, 15:38 عصر
بهترین راه :

Form2 f2 = new Form2();
Hide();
f2.ShowDialog();


امید وارم مفید باشه