PDA

View Full Version : سوال: سوال در مورد استفاده از userControl یا کلاس؟



va2012
سه شنبه 30 آبان 1391, 11:19 صبح
سلام

دوستان چند تا سوال در مورد نحوه صحیح برنامه نویسی شی گرا داشتم.

حتما میدونید که یکی از اصول برنامه نویسی شی گرا این هست که ما بیایم یک مسئله (پروژه) بزرگ رو به چند قسمت کوچکتر تقسیم کنیم که هم نظم و ترتیب کدهامون بیشتر بشه و هم بعدها که خواستیم پروژه رو تغییر یا توسعه بدیم کارمون راحت تر باشه و قابلیت استفاده مجدد داشته باشه و کد نویسی کمتر بشه و چندین مزایای دیگه.

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

اما حالا چند تا سوال درباره این شیوه برنامه نویسی دارم ممنون میشم راهنمایی کنید :

1- من اومدم ظاهر فرم اصلی برنامه رو به چند قسمت مختلف تقسیم بندی کردم و بعد هر قسمت رو در یک userControl قرار دادم و بعد فیلدها و متدهای مورد نیاز رو برای هر userControl به صورت جداگانه تعریف کردم .

اما مشکل اینجاست که برخی از این userControl ها دارای متدهای متشابهی هستند که میشه داخل یک کلاس جداگانه قرارشون داد تا نیاز نباشه برای هر کدوم یکبار به صورت جداگانه تعریف بشه . ولی اگر این کار رو بخوام انجام بدم چون در کلاس جدید به کنترل های موجود در هر userControl دسترسی ندارم مجبور میشم خاصیت Modifiy اون کنترل ها رو به Public تغییر بدم که از خیلی از دوستان شنیدم این کار درستی نیست.

پس در چنین مواقعی باید چه کار کرد؟ باید همون userControl ها رو استفاده کنم یا نه در کنار اون ها از یک کلاس جداگانه که شامل متدها و فیلدهای تکراری این userControl هاست استفاده کنم؟

البته میدونم که هر userControl هم خودش دارای یک کلاس هست که میشه متدها و فیلدها رو داخل اون تعریف کرد اما بحث من سر موارد تکراری هست.

2 - مگه یک userControl نمونه ای از یک فرم نیست؟ پس چرا نمیشه یک userControl ساخت که از یک کنترل مثل DataGridView ارث بری کنه؟

3- من از کد زیر برای ارتباط بین فرم ها در برنامه استفاده میکنم اما نمیدونم چرا نام کنترل ها باید به صورت رشته نوشته بشه چون در طول طراحی یک برنامه ممکنه چند بار نام یک کنترل رو تغییر بدیم ولی این تغییرات در کد زیر اعمال نمیشه . منظورم اینه که چرا این کدها مثل موقعی که از یک فرم نمونه میسازیم و موقع درج نام اون نمونه همه کنترل های public فرم در intlisense نمایش داده میشن نیست؟ :

(Application.OpenForms["MainForm"] as mainForm).Controls ...

va2012
سه شنبه 30 آبان 1391, 14:45 عصر
هنوز منتظرم. کسی راهنمایی نمیکنه؟

danialafshari
سه شنبه 30 آبان 1391, 15:50 عصر
دوست عزیز سوالت رو تقسیم کن و کوتاه و در چندین تاپیک
شخصا خودم تاپیگ بالای 4 خط رو نمی خونم

va2012
سه شنبه 30 آبان 1391, 16:11 عصر
دوست عزیز سوالت رو تقسیم کن و کوتاه و در چندین تاپیک
شخصا خودم تاپیگ بالای 4 خط رو نمی خونم

شما درست میگید اتفاقا منم حوصله خوندن پست های طولانی رو ندارم اما فکر نکنم برای دو تا سوال که به هم ربط دارن احتیاج باشه تاپیک جداگانه زد. اینجوری سایت پر میشه از پست های تکراری و ... توی همین سایت ما پست های 1 کیلومتری هم داریم !!!

hakim22
سه شنبه 30 آبان 1391, 17:01 عصر
1 - به تجربه میگم که از UserControl فقط برای کلاسهایی که نمایش ظاهری دارند استفاده کنید یا کلاسهایی که میخواهید به صورت تجاری بفروش برسانید در غیر این صورت همیشه منظور از شکستن برنامه به قسمتهای کوچکتر کلاسهای مجزا درون فایلهای Class Library یا همون DLL ها هستش.

2- از بعضی از کنترلها امکان ارث بری وجود نداره ولی DataGridView جز اونها نیست و نمیدونم چرا این سوال رو پرسیدید

3- همونطور که خودتون گفتید فرمها هم کلاس هستند و شما نمی توانید مستقیما از درون کلاس ( فرم اصلی) به یک فرم دیگر ( یک کلاس دیگر) بدون نمونه سازی از آن دسترسی پیدا کنید.

روش شما در فراخوانی فرمهای دیگر تلاشی است که بدون کد نویسی در مورد فرمها بخواهید مقادیر درون کنترلهای اونها رو تغییر بدیم.
CS بر عکس VB در این مورد خیلی سختگیر است و اجازه نمیدهد شما اشیای درون فرم دیگر را به روش مستقیم تغییر دهید. ( دلیلش خیلی مفصل است ولی بیشتر برای جلوگیری از باگهای ناخواسته است. )

چند راه برای غلبه بر این مشکل وجود دارد

یک روش این است که یک متد از نوع public در فرم دوم بسازید و آن را فراخوانی کنید.
یا مقادیری که میخواهید به فرم دوم ارسال کنید در Constructor فرم جاسازی کنید.
یا یک متغیر از نوع Static در یک کلاس جانبی تعریف کنید و با آن ارتباط برقرار کنید. ( 5 یا 6 راه وجود دارد)
پیشنهاد من این است که این مقاله را مطالعه کنید :
http://www.dreamincode.net/forums/topic/75208-passing-data-between-forms-in-c%23/

va2012
سه شنبه 30 آبان 1391, 18:49 عصر
ممنون از پاسختون

در مورد سوال آخر شما اون کد رو که نوشتم برای دسترسی به متدهای عمومی یک کلاس دیگر صحیح تر میدونید یا اینکه اول از کلاس مورد نظر یک نمونه ساخته بشه و بعد به متدهای اون کلاس دسترسی داشته باشیم؟ منظورم اینه که کدوم یک از این دو کد صحیح تر هست؟

(Application.OpenForms["Form2"] as Form2).Controls[].Sumnumber()




Form2 x = new Form2();
x.SumNumber()

اما در مورد پاسخ دوم من منظورم این بود که وقتی شما یک userControl رو از یک کنترل دیگه مثل DataGridView ارث میبرید و میخواید در محیط طراحی خصوصیات اون کنترل رو تغییر بدین تا یک DataGridView سفارشی با ظاهر مورد نظرتون داشته باشین دیگه در محیط طراحی نمیشه به اون DataGridView دسترسی داشت و فرم به صورت چند تا آیکن نمایش داده میشه !!!

فکر کنم برای این موارد باید از Class library استفاده کنیم نه userControl درسته؟

hakim22
چهارشنبه 01 آذر 1391, 10:28 صبح
روش دوم تنها روش صحیح در برنامه نویسی شی گراست مگر اینکه شما نام فرمها و کلاسهای اونها ندونید ( مثلا اونها به صورت یک plug-in به برنامه اضافه شده باشند و برنامه رو خیلی باز نوشته باشید)

شما میتوانید یک UserControl بسازید و یک DataGrid رو به همون روش که در WinForm به فرم اضافه می کنید به محیطش اضافه کنید.

بعدش هم ترسیم کردن DataGrid چه سودی برای شما داره ، روش که نمیشه نقاشی کنید ! برای تغییر ظاهرش باز باید برنامه نویسی کنید و روی Paint آن کد نویسی کنید