صفر تا صد ساخت بازی با سی شارپ 5#

صفر تا صد ساخت بازی با سی شارپ 5#
در جلسه قبلی با کنترل هایی که در این پروژه لازم داریم آشنا شدیم. این جلسه شروع کار با پروژه است. از این قسمت به بعد روی پروژه ای که از اول به شما قول داده بودیم کار می کنیم. ممکن است برای بعضی از دوستان کهنه کاری که به امید ساخت یک بازی حرفه ای با ما همراه بودند، بازی که خواهیم ساخت بسیار ساده به نظر برسد.
خرید شارژ ایرانسل
خرید شارژ ایرانسل، همراه اول، رایتل | خرید بسته های اینترنت ایرانسل | etore.ir
خرید سرور مجازی
ارائه سرور مجازی SSD NVMe برای اولین بار در ایران ؛ نهایت سرعت را تجربه کنید.
خرید شارژ ایرانسل
خرید شارژ ایرانسل، همراه اول، رایتل | خرید بسته های اینترنت ایرانسل | etore.ir
خودتان را اینجا معرفی کنید

که خب هیچ اشکالی ندارد هر کس تفکر خود را دارد و ما به همه سلیقه ها و طرز فکرها احترام می گذاریم. اما دوستان عزیز این نکته را فراموش نکنید که این فقط یک مقاله آموزش مقدماتی سی شارپ است و نباید انتظار ساخت بازی حرفه ای مثل Call Of Duty را از ما داشته باشید. در واقع بازی ساختن و پولدار شدن تنها بهانه ای برای آموزش دادن سی شارپ به دوستان تازه کار بود. اما بعنوان یک خوره کامپیوتر و یک برنامه نویس فکر می کنم که تنها سد میان شما و موفقیت پشتکار و قوه خلاقیت شماست. زبان برنامه نویسی که یاد می گیرید، تنها ابزار رسیدن به این موفقیت هستند و نه مسیری که با طی کردن آن به موفقیت برسید. این نکته را فراموش نکنید که هر ایده ای که به ذهن شما خطور می کند، ممکن است برای شما جذاب و اغوا کننده باشد ولی برای دیگران بی معنی و بلا استفاده باشد. ولی همیشه هر محصولی مشتری خاص خود را دارد، ایده شما نیز یک محصول است و هر چقدر هم که ساده باشد و حتما در میان حدود هفت میلیارد جمعیت زمین، میلییون ها مشتری دارد. پس اگر رویایی در سر دارید از سرزنش ها و زخم زبان های دیگران دلسرد نشوید. رسیدن به موفقیت آسان نیست و مشکلات بر سر راه افراد موفق بیشتر از بقیه مردم است. پس تنها انسانهای که اراده قوی، اعتماد به نفس و عشق به کارشان را دارند موفق می شوند.
 
خب بر گردیم سر کار خودمان. برای شروع کار ابتدا باید یک پروژه بسازید، سعی کنید که این پروژه را در جایی از هاردتون ذخیره کنید که می دونید بعدا فراموش نمی کنید یا پاک نمی شود، چون از اینجا به بعد ما فقط روی همین پروژه کار می کنیم. بازی که ما قصد درست کردن آن را داریم، یک بازی قدیمی و معروف به نام Galaxian است که اولین بار برای کنسول آتاری ساخته شد. تصاویری که از محیط بازی در زیر قرار دادیم کم و کیف و کلیت آن را به شما نمایش می دهد. شما هر نامی که می خواهید برای آن در نظر بگیرید اما ما نام آن را The Guards به معنی محافظین گذاشتیم.
 

 
حالا که با فضای نهایی بازی آشنا شدید، دید بهتری نسبت به موضوع خواهید داشت. حالا اگر پروژه بازیتان را ساختید با هم ادامه می دهیم.
برای شروع اول باید فندانسیون بازیمان را بسازیم، یعنی جایی که قرار است محیط بازی روی آن قرار گیرد. پس Form1 رو باز کنید و تغییرات لازم را روی آن اعمال کنید. مطمعنا بازی که می سازیم باید کل صفحه نمایش کاربر را پوشش بدهد. پس لازم است که فرم ما بصورت FullScreen نمایش داده شود. اما این کار باعث به وجود آمدن یک مشکل می شود، مشکل این است که رزولوشن دستگاهها ممکن است متفاوت باشد و مدیدریت این کار که بازی در هر رزولوشنی بصورت FullScreen کار کنه فعلا برای ما ممکن نیست، زیرا برای اینکار باید در سی شارپ حرفه ای تر شوید شاید در آموزش دوره پیشرفته اینکار را انجام دادیم. اما الان با این مشکل چطور کنار بیایم؟ خب راه حل ما این است که از کاربر بخواهیم رزولوشن دستگاه خود را با بازی هماهنگ کند. برای اینکار ما یک رزولوشن در نظر می گیریم و چک می کنیم اگر رزولوشن دستگاه فرق داشت از کاربر می خواهیم که رزولوشن دستگاهش را تغییر بدهد.
*نکته : از اینجا به بعد بدلیل زیاد بودن تغییرات در ویژگی های کنترل ها از شکل زیر برای آنها استفاده می کنیم.

مقداری که باید باشد     =     نام ویژگی
 
پس وارد قسمت طراحی بشوید و روی فرم کلیک کنید و تغییرات زیر رو اعمال کنید.
Name = frm_main
Size = 1280,800
FormBorderStyle = Fixed3D
MaximizeBox = False
MinimumBox = False
RightToLeft = Yes
StartPosition = CenterScreen
نامی که برای بازیتان در نظر گرفتید = Text
 
همانطور که دیدید صفحه نمایش ما به دو قسمت تقسیم شد سمت راست که قسمت تنظیمات بازی است و سمت چپ که محل نمایش خود بازی است. پس باید صفحه را  به دو بخش تقسیم کنیم برای اینکار از SplitContainer استفاده می کنیم که بهترین گزینه برای اینکار است، پس یک کنترل SplitContainer روی صفحه قرار دهید.
Name = spc_main
Dock = Fill
 
 در پنجره Properties دنبال ویژگی splitContainer1.Panel1 یک بگردید و خاصیت Panel1MinSize را به 300 تغییر دهید، مشاهده خواهید کرد که ویژوال استودیو خطا می گیرد و اجازه اینکار را به شما نمی دهد، علت این است که در حال حاظر اندازه spn_main کمتر از اندازه ای است که شما می خواهید به پنل سمت راست آن اختصاص دهید. وقتی برای سایز یک کنترل از ویژگی Dock استفاده می کنید، سایز آن کنترل در زمان load شدن برنامه set می شود. در نتیجه عرض spc_main در زمان load فرم به اندازه عرض فرم در می آید. پس برای اینکه پنل ها به اندازه مورد نظر ما نمایش داده شوند باید آنها را در زمان load فرم اندازه بدهید، پس به قسمت کد بروید و کد زیر را وارد کنید.
spc_main.Panel2MinSize = 900;
 
با تنظیم این ویژگی دیگر سایز panel سمت چپ از 900 کمتر نخواهد شد و panel سمت راست هم اتوماتیک وار مقدار می گیرد. برای اینکه متوجه بشوید که مرز این دو panle در زمان اجرا کجاست، می توانید در محیط طراحی روی یکی از آنها کلیک کنید و ویژگی BackColor آن تغییر دهید و برنامه را اجرا کنید.
panel سمت چپ قسمت بازی است و باید یک پس زمینه داشته باشد. برای اینکار از PictureBox استفاده می کنیم. یک کنترل PictureBox روی panel سمت چپ اضافه کنید.
Name = ptb_backGround
Dock = Fill
 
بعدا در برنامه هنگام تغییر تم بازی به ویژگی Image این کنترل مقدار دهی می کنیم ولی فعلا برای اینکه کار کردن با آن راحت باشد یک عکس روی آن قرار می دهیم و ویژگی SizeMode آن را به StretchImage تغییر می دهید، این کار باعث می شود که هر عکسی که شما برای پس زمینه آن در نظر بگیرید به اندازه آن در بیاید، در اصل کشیده می شود وسعی کنید یک عکس با کیفیت انتخاب کنید تا پس از کشیده شدن بی کیفیت نشود. شمای کلی برنامه شما باید به این صورت باشد.
 

فعلا کار ما با پنل سمت چپ تمام شد. حالا ToolBox را باز کنید و یک کنترل SplitContainer روی پنل سمت راست بیاورید.
Name = spc_rightPanel
Orientation = Horizontal
 
می بینید که spc_rightPanel به حالت افقی در می آید. حالا خط وسط دو پنل آن را بگیرید و آن را به دو قسمت تقسیم کنید. سپس یک کنترل GroupBox روی پنل بالایی قرار دهید.
Name = gpb_userInfo
Anchor = Top,Left,Right
Font = Tahoma, 9pt
مشخصات کاربر = Text
 
یک کنترل GroupBox دیگر هم به آن اضافه کنید. GroupBox دوم را زیر قبلی قرار دهید.
Name = gpb_gameInfo
Anchor = Left,Right,Bottom
Font = Tahoma, 9pt
تنظیمات بازی = Text
 
gpt_userInfo قسمتی است که کاربر باید نام خودش را ثبت کند. درون این قسمت یک کنترل lable قرار دهید.
name = lbl_username
نام  : = Text
 
سپس یک کنترل TextBox روبروی آن قرار دهید.
Name = txt_username
 
روی  gpt_gameInfo کلیک کنید و یک کنترل label روی آن قرار دهید.
 
Name = lbl_Theme
Text = : تم بازی را انتخاب کنید 
 
برای انتخاب تم بازی از کنترل ComboBox استفاده می کنیم.

Name = cmb_Theme
Items = نام هر تمی که می خواهید به بازی اضافه کنید در این لیست بنویسید
 
در این بازی کاربر می تواند با ماوس یا کیبورد شلیک کند، به این منظور از RadioButton استقاده می کنیم، زیرا کاربر فقط می تواند یکی را انتخاب کند. اگر شما می خواهید که کاربر بتواند همزمان با کیبورد و ماوس شلیک کند می توانید از CheckBox استفاده کنید. اما ما همان RadioButton را استفاده می کنیم. پس دو عدد از این کنترل روی فرم قرار دهید.
 
Name = rdb_Keyboard
Text =   شلیک با کیبورد
 
Name = rdb_Mouse
Text = شلیک با ماوس
 
کار ما با  gpt_gameInfo هم تموم شد. حالا زیر این کنترل باید دو کنترل Button اضافه کنید. از این دو کنترل برای شروع و توقف بازی استفاده می کنیم.
 
Name = btn_start
Text =  شروع
Name = btn_stop
Text = توقف
Enable = false
 
چرا ویژگی Enable دکمه توقف را مساوی false قرار دادیم؟ زمانی که هنوز بازی شروع نشده است، متوقف کردن آن معنی نمی دهد، پس تا زمانی که بازی کن روی دکمه شروع کلیک نکرده است، دکمه توقف غیر فعال است.
ساخت پنل بالا به اتمام رسید برنامه شما الان باید مانند تصویر زیر شده باشد.
 

خب تا به اینجا تقریبا تمام موارد مورد نیاز را برای شروع کار داریم. یکبار برنامه را اجرا کنید می بینید که غیر از نام که باید توسط کاربر پر شود، تم بازی و نحوه شلیک انتخاب نشده اند و اگر بازی ما کامل باشد بازی کن می تواند بدون انتخاب تم و یا نحوه شلیک وارد بازی شود و با اینکار برنامه ما دچار اشکال می شود. برای رفع این مشکل دو راه وجود دارد، اول اینکه در زمان شروع بازی چک کنیم و ببینیم کاربر همه کنترل ها را پر کرده است یا خیر. دوم اینکه یک مقدار اولیه برای این کنترل ها در نظر بگیریم. ما از روش دوم استفاده می کنیم و به کنترل ها مقدار اولیه اختصاص می دهیم. حالا کجا باید این مقادیر اولیه را به کنترل ها اختصاص داد ؟ برای اینکار می توانیم از رخداد load فرم استفاده کنیم، همچنین می شود از تابع سازنده فرم هم استفاده کرد، زیرا این تابع هم دقیقا زمانی اتفاق می افتد که فرم ساخته می شود و من ترجیح می دهم از تابع سازنده استفاده کنم، زیرا در آینده در رخداد load فرم کدهای زیادی قرار می گیرند و باعث سر درگمی ما خواهد شد، پس حتما توضیحاتی رو برای هر خط کد بنویسید تا در آینده به مشکل نخورید. در نتیجه از این به بعد تمام مقداردهی های اولیه را در تابع سازنده فرم انجام می دهیم. کد زیر رو در تابع سازنده frm_main بنویسید.

 
cmb_Theme.SelectedIndex = 0;
rdb_Keyboard.Checked = true;
 
در اولین خط این کد، از درون مجموعه ای که در زمان طراحی ظاهر برنامه برای cmb_Theme تعریف کردیم اولین عنصر را بعنوان پیش فرض در نظر می گیریم. در اصل SelectedIndex یک ویژگی property)) از ComboBox ها است که مشخص می کند کدام یک از اعضا مجموعه درون ComboBox انتخاب شده اند و چون می دانیم که مجموعه ها در سی شارپ از 0 شروع می شوند، عدد 0 را برای آن انتخاب کردیم تا اولین عنصر این مجموعه انتخاب شود.
فرض کنید کاربر تنظیمات لازم رو انجام داده است  و حالا دکمه شروع بازی را زده است، از اینجا به بعد کاربر نباید بتوانند تنظیمات را تغییر دهد. پس باید به قسمت رخداد کلیک دکمه شروع برویم و کد زیر را در آن وارد کنیم.
 
gpb_userInformation.Enabled = false;
gpb_gameInformation.Enabled = false;
btn_start.Enabled = false;
btn_stop.Enabled = true;
 
همانطور که می بینید با غیر فعال کردن GroupBox ها و دکمه شروع کاربر دیگر نمی تواند در میان بازی نتظیمات را تغییر دهد. اما کاربر باید بتواند بازی را متوقف کند ولی ما در همان شروع برنامه دکمه توقف بازی را غیر فعال کردیم پس حالا باید این دکمه را به حالت فعال برگردانیم درست مطابق کد بالا که این کار را انجام می دهد.
در این قسمت چون قرار بصورت قسمت به قسمت پیش بریم مجبوریم کمی کد نویسی کنیم، اینکار باعث می شود که هم از سنگین شدن کار در جلسات بعدی کاسته شود و هم فهم کد ساده تر شود.
در این قسمت از برنامه باید یکی دیگر از مفاهیم اصلی مربوط به متغییر ها رو براتون توضیح بدم، البته این امکان وجود داشت که در همان قسمت متغییر ها یعنی همون جلسات اول در مورد این مفهوم صحبت کنیم، اما ترجیح دادیم که این قسمت را در اینجای کار توضیح بدهیم که برای شما عزیزان ملموس تر باشد و همچنین جلسات اول خیلی پیچیده نشود و اما این مفهوم چیست؟

متغییرهای محلی و متغییر های سراسری

رخداد load فرمتون رو بسازید و درون آن یک متغییر از نوع String بسازید و نام آن را playerName قرار بدید. سپس ویژگی Text کنترل txt_username را درون آن بریزید. حالا به قسمت طراحی برگردید و روی دکمه شروع دوبار کلیک کنید تا رخداد کلیک آن ساخته شود. در درون این رخداد سعی کنید تا کلمه  “MajidOnline” را درون آن قرار دهید، مشاهده می کنید که متغییر playerName توسط منوی IntelliSense نمایش داده نمی شود و اگر خودتان آن را بنویسید و برنامه را اجرا کنید، برنامه شما یک خطا مبنی بر اینکه چنین متغییری تعریف نشده است نمایش می دهد و اجرا نمی شود. شما که این متغییر را تعریف کرده بودید پس علت چیست؟
دلیل این است که متغییر playerName در بلاک رخداد load فرم شما ساخته شده است و فقط در همان بلاک قابل دسترسی است. بطور کلی متغییر ها به دو صورت سراسری و محلی تعریف می شوند. متغییرهای که بصورت محلی تعریف شوند غیر از بدنه خود آن متد در جای دیگری از برنامه قابل استفاده نیستند. اما متغییرهایی که بصورت سراسری تعریف بشوند، در هر قسمت از برنامه قابل دسترسی هستند.
اما چرا باید متغییرها رو بصورت سراسری تعریف کنیم ؟ خب این بستگی به هدف ما در برنامه داره گاهی لازم که در چند متد مختلف به یک متغییر دسترسی داشته باشیم و ازش استفاده کنیم بنابراین مجبوریم که متغییرها رو بصورت سراسری تعریف کنیم.
حالا چطور باید یک متغییر سراسری تعریف کرد؟ خیلی ساده فقط کافیه که به قسمت کد برنامتون برگردید و مثل تصویر زیر متغییری (با فلش سبز مشخص شده است) که می خواهید سراسری باشد رو بین این دو خطی که در تصویر زیر با فلش قرمز مشخص شده اند قرار دهید.
 
 

همانطور که در تصویر می بینید ویژگی Text از کنترل  txt_username را درون متغییر قرار نداده ایم. شما می توانید اینکار رو امتحان کنید. مشاهده می کنید که برنامه شما خطا دارد. علت این خطا در ساختار اجرای یک برنامه است و نیازی نیست که فعلا ذهن خودتون رو درگیر این مسئله کنید. فقط این نکته را بخاطر داشته باشید که برای مقدار دهی اولیه متغییرهای سراسری باید بطور مستقیم به آنها مقدار دهی کنید و نمی شود از کنترل ها برای مقدار دهی به آنها استفاده کنید. مثال :
 
string playerName = "MajidOnline";
 
شاید این سوال پیش بیاید که چرا این مطلب رو توضیح دادم؟ زیرا در طول ساخت بازی ما از متغییرهای زیادی استفاده می کنیم که باید در سراسر برنامه قابل دسترسی باشند، نگران نباشید در طول ساخت بازی با این موضوع کار خواهید کرد. در جلسه بعدی چندین متغییر سراسری تعریف خواهیم کرد. برای این جلسه کافی است اما فراموش نکنید که آهسته آهسته وارد کد نویسی می شویم. پیشنهاد می کنم که پیش از جلسه قبل نگاهی به جلسات دوم و سوم داشته باشید و همچنین ظاهر بازی خودتون رو طراحی کنید. لطفا نظراتتون رو با ما در میان بگذارید.
 
 
 

مصطفی مدرک کارشناسی نرم افزار دارد و از برنامه نویسان شرکت آرتیمان استودیو است. از سال 86 برنامه نویسی با زبان سی شارپ را آغاز کرده و در حوزه توسعه وب با تکنولوژی دات نت بسیار مسلط است. وی هم اکنون در حال توسعه اپلیکیشن های موبایل از طریق پلتفرم زامارین است.

نظرات و سوالات کاربران

ارسال پاسخ پونه
پونه
جمعه ۰۳ دی ۱۳۹۵ ۲۳:۰۵
باسلام ، ممنون از مطالب عالیتون، یه سوال داشتم درمورد تابع سازنده . من مرحله به مرحله با توضیحاتتون پیش میرم . اما متاسفانه متوجه موضوع تابع سازنده نشدم . اینکه کجاست و چه فرقی با فرم لود داره ؟
ارسال پاسخ احمد
احمد
شنبه ۱۵ خرداد ۱۳۹۵ ۱۲:۰۰
ممنون بابت مطلب عالیتون
چرا از اندروید استدیو استفاده نمیکنید؟ فرقشون چیه؟ کدوم بهتره؟
با تشکر
ارسال پاسخ مصطفی درخشان
مصطفی درخشان
یکشنبه ۲۲ شهریور ۱۳۹۴ ۱۱:۰۵
در پاسخ به دیدگاه علی ارسال شده در یکشنبه ۲۲ شهریور ۱۳۹۴ ۰۰:۳۹

خیلی ممنون از جواب شما
فقط چرا این نسخه رایگانه؟نسخه آزمایشیه؟باگ امنیتی داره؟امکانات کمتری داره؟درکل آیا برنامه نویسی حرفه ای C# (هم ویندوز هم اندروید)باهاش ممکنه و ضرری ایجاد نمیکنه؟
Mono android هم جایی که بفروشه یا نسخه ای که رایگان باشه یا مشابه رایگان نمیشناسین؟همونطور که گفتم کرک نمیخوام و میخوام کاملا شرعی باشه.

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

/www.monodevelop.com/download" rel="nofollow">http://www.monodevelop.com/dow...
monodevelop یک محیط برنامه نویسی برای #C و #F است، که کاملا مجانیه پس با خیال راحت استفاده کنید.
این لینک هم برای دانلود monoandroid
/www.monodevelop.com/archived/download/mono-for-android" rel="nofollow">http://www.monodevelop.com/arc...

امیدوارم که تونسته باشم به شما کمک کنم.

ارسال پاسخ علی
علی
یکشنبه ۲۲ شهریور ۱۳۹۴ ۰۰:۳۹

خیلی ممنون از جواب شما
فقط چرا این نسخه رایگانه؟نسخه آزمایشیه؟باگ امنیتی داره؟امکانات کمتری داره؟درکل آیا برنامه نویسی حرفه ای C# (هم ویندوز هم اندروید)باهاش ممکنه و ضرری ایجاد نمیکنه؟
Mono android هم جایی که بفروشه یا نسخه ای که رایگان باشه یا مشابه رایگان نمیشناسین؟همونطور که گفتم کرک نمیخوام و میخوام کاملا شرعی باشه.

ارسال پاسخ مصطفی درخشان
مصطفی درخشان
شنبه ۲۱ شهریور ۱۳۹۴ ۰۹:۴۳

خیلی ممنون از اینکه نظرات تون رو با ما در میون گذاشتید. در مورد سوال splitcontainer خدمت شما دوست عزیز عرض کنم که در زمان طراحی فرم شما به اندازه ای نمایش داده می شود که در پنجره ویژوال استودیو جا شود و زمانی که شما به فرم اندازه ۱۲۰۰٫۸۰۰ می دهید٬ تغییری در اندازه فرم (در زمان طراحی) ایجاد نمی شود. در واقع فرم شما در زمان اجرا به اندازه ۱۲۰۰٫۸۰۰ نمایش داده می شود. splitcontainer ای هم که روی فرم قرار دادید بصورت نسبی سایز گرفته است. یعنی اگر فرم بزرگتر شود splitcontainer هم بزرگتر می شود. اما چون در زمان طراحی فرم کوچکتر است splitcontainer هم کوچکتر است و شما نمی توانید به یکی ازپنل های آن سایز بزرگتر از سایز خود splitcontainer بدهید٬ پس اگر شما سایز یکی از پنل های آن را بزرگتر از سایز خود splitcontainer در نظر بگیرید٬ ویژوال استودیو اجازه این کار را به شما نمی دهد. اما ویژگی Panel1MinSize باعث می شود که پنل یک در زمان اجرا کوچکتر از ۳۰۰ پیکسل نشود. همانطور که قبلا هم گفتم اگر بخواهیم سایز پنل ها رو بطور دقیق مشخص کنیم باید از طریق محیط کد این کار رو انجام بدیم. در این مثال کمترین سایز پنل دوم رو ۹۰۰ در نظر گرفتیم. این پنل در زمان اجرا کوچکتر از ۹۰۰ نخواهد شد٬ در نتیجه اندازه پنل یک به اندازه باقیمانده عرض splitcontainer می شود ( یعنی ۳۰۰ پیکسل). امیدوارم که این توضیحات به شما کمک کند. اما اگر هنوز جواب سوالتون رو نگرفتید٬ لطفا مجدد بپرسید.
اما در مورد سوال دوم باید بگم که بنده اطلاعاتی در این مورد ندارم٬ فقط می تونم بگم که شرکت مایکروسافت ورژن visual studio community 2015 رو بصورت مجانی منتشر کرده. شما می تونید از سایت خود این شرکت این برنامه رو دانلود کنید و با خیال راحت استفاده کنید .

ارسال پاسخ MEHRAD77
MEHRAD77
جمعه ۲۰ شهریور ۱۳۹۴ ۱۶:۲۲

مرسی :)

ارسال پاسخ علی
علی
پنج شنبه ۱۹ شهریور ۱۳۹۴ ۰۳:۵۹

فوق العاده عالی بود.فقط این قسمت به نظرم مبهم بود ودرست نفهمیدم خواهشا دوباره توضیح بدین:
"در پنجره Properties دنبال ویژگی splitContainer1.Panel1 یک بگردید و خاصیت Panel1MinSize را به 300 تغییر دهید، مشاهده خواهید کرد که ویژوال استودیو خطا می گیرد و اجازه اینکار را به شما نمی دهد، علت این است که در حال حاظر اندازه spn_main کمتر از اندازه ای است که شما می خواهید به پنل سمت راست آن اختصاص دهید. وقتی برای سایز یک کنترل از ویژگی Dock استفاده می کنید، سایز آن کنترل در زمان load شدن برنامه set می شود. در نتیجه عرض spc_main در زمان load فرم به اندازه عرض فرم در می آید. پس برای اینکه پنل ها به اندازه مورد نظر ما نمایش داده شوند باید آنها را در زمان load فرم اندازه بدهید، پس به قسمت کد بروید و کد زیر را وارد کنید.
spc_main.Panel2MinSize = 900;

با تنظیم این ویژگی دیگر سایز panel سمت چپ از 900 کمتر نخواهد شد و panel سمت راست هم اتوماتیک وار مقدار می گیرد."

درضمن اینکه شرکت سازنده ویژوال استودیو و mono android (که فکرکنم بعدا استفاده میکنین) مال کدوم کشوره و جزو کشورهای کافرحربی محسوب میشن یا نه؟
چون من از مرجع تقلیدم آقای مکارم شیرازی سوال کردم و گفتند استفاده از نسخه غیرقانونی برنامه های پولی چه خارجی و چه ایرانی حرام و درآمد حاصل از اون هم حرامه و باید اورجینال خریداری بشه به جز برنامه هایی که متعلق به کشورهای کافر حربی هستند.
قیمت این دوبرنامه چه قدر است؟اصلا این دوبرنامه مخصوصا برنامه دوم درایران به فروش میروند و اگر بله کجا؟
ازوقتی هم که واسه نوشتن آموزش و ترویج علم میذارین ممنونم.