SajjadKhati
کاربر فعال <A href="http://forum.majidonline.com/f
این شیء ای که از نوع <Enumerable<UIElement بر میگردونه، چی به foreach تحویل میده؟ طبق توضیحات foreach با GetEnumerator اش یک IEnumerator تحویل میده. حالا این IEnumerator منبع اش کدوم مجموعه است؟ خودش مستقلا یک مجموعه داخلش داره و اعضاء خودش رو بر میگردونه؟ یا <Enumerable<UIElement ئه یک مجموعه کپی از روی NewControls برای خودش ایجاد کرده و اعضاء اون رو بر می گردونه؟ یا مستقیما اعضاء NewControls رو بر میگردونه؟
امتحان کنید و ببینید :
C#:var userControl = new UserControl(); var newControls = new UIElementCollection(userControl, userControl); var enumerable = newControls.Cast<UIElement>(); var enumerator = enumerable.GetEnumerator(); var fieldInfo = enumerator.GetType().GetField("source", BindingFlags.NonPublic | BindingFlags.Instance); var source = fieldInfo?.GetValue(enumerator); if (source == newControls) { MessageBox.Show("yes"); }
اینکه نوع دو شیء متفاوت از هم باشند به رفتار Enumerable هاشون ربطی نداره.
C#:public class A : IEnumerable<int> { public static readonly List<int> Source = new List<int>(new[] { 1, 2, 3 }); public IEnumerator<int> GetEnumerator() { return Source.GetEnumerator(); } IEnumerator IEnumerable.GetEnumerator() { return GetEnumerator(); } } public class B : IEnumerable<int> { public IEnumerator<int> GetEnumerator() { return A.Source.GetEnumerator(); } IEnumerator IEnumerable.GetEnumerator() { return GetEnumerator(); } }
C#:var b = new B(); foreach (var i in b) { A.Source.Sort(); }
سلامی مجدد
خیلی ممنون استاد .
یه چیزهایی متوجه شدم .
اما ان شاء ا... بعدا قضیه ی Enumerator و Enumerable را باید از اول مرور کنم تا کامل متوجه شم .
تشکر استاد .
اولا شما دارید یک Model ای رو توصیف می کنید که واسط پیچیده ای داره، طراحی بدی داره. ساختار داده داخلش به خودش مربوط ئه، ممکنه هزار تا کلاس داخل خودش استفاده کنه که private باشند، ایرادی نداره، اما واسطی که به محیط خارج از خودش ارائه میکنه نباید دردسر ساز باشه، نباید زیادی پیچیده باشه. اگر Model طراحی خوبی داشته باشه نباید برای تعامل با ViewModel بار زیادی روی دوش ViewModel بندازه.
ثانیا دو گروه کلاس متفاوت هست، شما گروه دوم رو قاطی گروه اول کرده اید. در گروه اول کلاس ها مربوط به استفاده داخلی Model هستند، فرضا در بانک اطلاعاتی هر فردی یک مشخصاتی داره که با یک کد منحصر بفرد (کلید خارجی) در جدول ربط داده میشه به جدول دیگری. کلاسی که حاوی این کلید خارجی است مربوط به بانک اطلاعاتی است، فقط مربوط به Model ئه، قرار نیست به View منتقل بشه. اما در گروه دوم انواع کلاس ها رو دارید که از اساس ساخته شده اند برای تبادل داده، کارشون سادگی تبادل داده بین Model و View ئه، فرضا کلاسی که مشخصات پرسنل رو منتقل می کنه، نه میدونه جدول چیه و نه کاری با کلید جداول داره. این کلاس میتونه داخل ViewModel تعریف بشه، نه در Model، نه در View.
این Model طراحی بدی داره.
من هم برای پروژه هام یه کلاس پایه تعریف میکنم . مثلا کلاس InteropWithUI و اعضایی را تعریف میکنم که به درد کل پروژه های دیگه بخوره و بشه از این کلاس در پروژه های دیگه ستفاده کرد و همچنین یه کلاسِ فرزند این کلاس تعریف میکنم بنام PoshtibangirToloUI که از InteropWithUI ارث بری میکنه و شامل اعضایی هست که فقط در پروژه ی PoshtibangirTolo ام کاربرد داره .
این برای قضیه ی View (در واقع بخشی از View) بود .
برای Model هم یه همچین کاری هم میکنم که یه کلاس پایه داشته باشه تا بعدا در هر پروژه ای بشه ازش استفاده کرد . یه کلاسی که اولِ نامش هم با PoshtibangirTolo شروع میشه رو میذارم که برای همین قضیه ی انتقال اطلاعات به ViewModel مخصوص پروژه ی PoshtibangirTolo و کلا اعضایی که فقط در این پروژه بکار میره ، در این کلاس باشه .
همچین چیزی ، خوبه؟
==========================
- بعد اینکه ، فرضا یه پروپرتی ای از نوع کلاسِ Student (از نوع Model) را درون کلاسِ ViewModel مون تعریف کردیم .
مقداردهی این پروپرتی (که درون ViewModel تعریف کردیم) ، فقط باید از درون خودِ کلاسِ ViewModel انجام بگیره و مقدار اولیه اش هم شیِ جدیدی از Student باید بهش بدیم دیگه . درسته؟
یعنی نمیتونیم در پارامتر متدی (یا در پارامتر متد سازنده) ، مقدار پروپرتیِ Student را از View بگیریم . چون در MVVM ، در یم View ، نمیتونیم از Model مون شی ای (حداقل ، بصورت صریح) ایجاد کنیم . درسته؟
پس مقداردهی اولیه ی اون پروپرتیِ نوع Student ، فقط و فقط باید در کلاسِ ViewModel انجام بشه (نه اینکه در کلاس های View انجام بشه و به ViewModel ، پاس داده بشه) و چون نمیتونه مقدارش را از View دریافت کنه ، پس برای مقداردهی اولیه ، حتما باید شیِ جدیدی از این پروپرتی ، در ViewModel ایجاد بشه .
همونطور که در اون پروژه بود .
درست میگم؟
- اگه این طور باشه ، پس با هر بار ساختنِ شی جدید از ViewModel ، در واقع با شیِ جدیدی از Model مون کار میکنیم (چون معمولا مقداردهی اولیه ی پروپرتی های ViewModel ، در متد سازنده انجام میشه) .
پس ، هر وقت که در کلاس های View بخوایم فقط با یک شی از Model (توسط ViewModel) کار کنیم ، پس باید با یک شی از ViewModel کار کنیم . درست میگم؟
معمولا در کلاس های مختلف View (مثل کلاس های Window ها و UserControl ها و Page ها و ...) که همه شون ، یک ظاهرِ نرم افزار را تشکیل میدن ، لازم داریم که با یک شی از Model (بصورت غیر مستقیم) کار کنیم . پس تا زمانی که این طور باشه ، پس با یک شی از ViewModel در View مون باید کار کنیم . درست میگم؟
و اگه این طور باشه ، لازمه که بین کلاس های View مون (مثل کلاس های Window ها و UserControl ها و Page ها و ...) ، اول فرضا در کلاس MainWindow ، شی ای از ViewModel که ساختیم ، به بقیه ی کلاس ها ، فقط همون شی (از ViewModel) را پاس بدیم . تا به این صورت ، فقط با یک شی از ViewModel کار کنیم .
یعنی در هر کلاسی از View مون (مثل کلاس های Window ها و UserControl ها و Page ها و ...) ، یک شیِ جدیدی از ViewModel نسازیم . وگرنه با اون کار ، ViewModel ، شیِ جدیدی از Model مون میسازه (البته تا مادامی که به شیِ جدیدی از Model در View ، توسط ViewModel نیازی نداشته باشیم) .
درست میگم؟
در مطالب قبلی صحبتش شده. وظیفه هر جزء رو در حد مسئولیت خودش در نظر بگیرید، یعنی فرضا اگر Model قراره موقع تغییر اطلاع بده، مسئولیتش در همین حد ئه که امکانی به ViewModel یا کلا هر موجودیت خارج از خودش بده که اگر خواست، بتونه از تغییر مطلع بشه، فقط همین. اینکه ViewModel به تغییر اهمیت میده یا نمیده، به View خبر میده یا نمیده یا چطور خبر میده به Model ربطی نداره.
همچین Model ای با INotifyPropertyChanged که میگه مقدار فلان مشخصه تغییر کرد، یا یک event خاص خودش میتونه به ViewModel تغییرات رو اطلاع بده. حالا اینکه ViewModel ای که ممکنه شخص دیگری نویسنده اش باشه به این تغییرات اهمیت میده یا نه یا در مقابل این تغییرات با View چه تعاملی بکنه دیگه به Model ربطی نداره.
بله .
حواسم تازه به INotifyPropertyChanged جمع شد .
با وجود INotifyPropertyChanged ، نیازی به اینکه پروپرتی ای از نوع View در ViewModel تعریف کنیم ، نداریم .
فقط کافی هه که رویداد PropertyChanged را در ViewModel متصل کنیم .
اون WinForm ای که میگید اسم پلتفرم داخل NET. ئه، طبعا وقتی خود NET Framework. سال 2002 ارائه شده، WinForm هم نمیتونسته زودتر از 2002 باشه، با خود NET. معرفی شده. اما قدمت Windows Forms که ربطی به NET. نداره، قبل از اینکه NET. ارائه بشه برنامه های تحت Windows Forms و زبان های برنامه نویسی ویژوال با پلتفرم Windows Forms بودند. یعنی از همون موقع که ویندوز این واسط کاربری رو داشته زبان های برنامه نویسی ویژوال اون دوران هم همچین پلتفرمی داشته اند.
احتمالا در مورد Windows Forms صحبت می کردم، Windows Forms یک پلتفرم خاص NET. نیست، فرضا در Visual Basic 5 (سال 1997) هم پلتفرم همون Windows Forms ئه.
بله.
WinForm و Windows Forms مگه فرق دارن؟!
در ویکی پدیا که هر دو را یکی زده .
من سندی از تاریخچه ی مجزایی از هر کدوم پیدا نکردم .
فقط توی ویکی پدیا ، هر دو را یکی میدونه و نسخه ی اولیه را وابسته به .net framework و انتشار اولیه شون را هم 2002 زده .
خیلی ممنون استاد