FirstName عضوی از کلاس Student هست، اما FirstName اون Binding که الزاما هدفش Student.FirstName نیست.
امتحان کنید، یک کلاس جدید شبیه Student که FirstName داشته باشه و یک کلاس جدید شبیه StudentViewModel بسازید که با اون کلاس جدید کار کنه و موقع کلیک روی یک دکمه شبیه اون کدی که در StudentViewControl_Loaded بود DataContext رو تغییر بدهید. کار می کنه. پس نمی توانید بگید FirstName ئه همون Student.FirstName ئه. بهش وابسته نیست، مستقل ئه. ممکنه با ده جور ViewModel دیگه سازگار باشه.
این View به Model وابستگی نداره.
در MVVM قراره بخش های View و Model مستقل و مجزایی وجود داشته باشه. مستقل بودن یعنی چی؟ یعنی ماهیت شون بهم وابسته نباشه.
سلامی مجدد
خیلی ممنون استاد .
اون Path برای Binding ای که مقدارش را Student.FirstName داده بودیم ، میدونیم که به معنای این هست که در شیِ DataContext (شیِ منبع) بعد از اینکه مشخص شد ، برو دنبال پروپرتیِ Student (حالا این پروپرتیِ Student ، از هر نوعی میتونه باشه) بگرد و همچنین درونِ شیِ این پروپرتیِ Student ، دنبال پروپرتی ای با نام FirstName بگرد و این پروپرتیِ FirstName را به پروپرتیِ شیِ هدف مون binding کن .
درسته دیگه؟
حالا منظورتون این هست که در این ساختار Binding ، میشه بجای پروپرتیِ Student که درون کلاس StudentViewModel و همچنین بجای پروپرتیِ FirstName که درون کلاس Student بود ، پروپرتی هایی را دقیقا با همین نام اما در یک کلاسِ دیگه (که نام کلاس متفاوت باشه) نوشت و این Binding هم اگه شیِ DataContext اش را عوض کنیم ، در اونجا هم کار میکنه .
درست متوجه ی منظورتون شدم؟ منظورتون همینه؟
در اون button_Click شما View رو وابسته می کنید به کلاس Student در Model. بدون وجود اون Model اون View تون تعریف اش ناقصه.
اگه منظورتون همونی هست که در بالا گفتم ، خوب برای وقتی که در رویداد کلیک دکمه ، مقدار :
C#:
this.StudentViewModel.Student.FirstName = "Shahid Mohsen";
را مشخص کردیم ، در اینجا هم میشه بجای پروپرتیِ Student که درون کلاس StudentViewModel و همچنین بجای پروپرتیِ FirstName که درون کلاس Student بود ، پروپرتی هایی را دقیقا با همین نام اما در یک کلاسِ دیگه (که نام کلاس متفاوت باشه) بنویسیم و در این حالت هم کار میکنه دیگه .
نمیدونم تونستم منظورم را برسونم یا نه .
=======================================================================
Data Binding و Commands
اگر بخواهید با الگوی طراحی MVVM پیش بروید باید از هر کدی شبیه به اون چیزی که نوشتید اجتناب کنید.
الان استاد ببینید ، من تصوری که از mvvm تا اینجا پیدا کردم ، چیزی شبیه به شکل های زیر هست . ببینید درستن؟
اول این رو بگم که با ارتباط بینِ ViewModel با Model ، مشکلی ندارم و متوجه شدم .
یعنی مشکلی ندارم که در اون تصویری اومد که اگه Model میخواد با ViewModel رابطه داشته باشه ، بهش Notification میفرسته و کلا اطلاع رسانی میکنه (حالا توسط پیاده سازیِ اینترفیس INotifyPropertyChanged یا هر روش دیگه ای) و همچنین ViewModel هم برای ارتباط با Model ، کار خاصی لازم نیست کنه و مستقیما شی ای از Model (که در درون کلاس ViewModel) را که در اختیار داره را تغییر میده (که همون نوشته ی "ViewModel Update The Model" در اون تصویر هست) .
تا اینجا را درست گفتم دیگه؟
اما مسئله ی من ، ارتباطِ View با ViewModel هست .
نکته ی اساسی ای که الان متوجه شدم اینه که View اصلا نباید کارهای تغییرِ اشیا و اعضای (مثل پروپرتی هایی که در) کلاس Model را خودش تغییر بده (یعنی اون کد که برای تغییر شی در رویداد کلیک دکمه که این رویداد جزء View محسوب میشد را نباید انجام میدادم . چون مستقیما خودش اومد عضو FirstName که عضوی از کلاس Model محسوب میشد را ولو با واسطه ای از شیِ ViewModel ، تغییر داد) .
بلکه نکته ی اساسی اینجاست که هر تغییری که View اگه بخواد روی (اشیا و اعضای کلاس های) Model انجام بده ، اول اینکه خودش نباید انجام بده و دوم اینکه باید برای انجام این تغییرات (روی اشیا Model) ، باید از ViewModel
درخواست کنه که این کار را براش انجام بده .
یعنی نکته ی اساسی اینجاست که اگه View بخواد با ViewModel ، ارتباط داشته باشه (منظورم رابطه ی برعکسش که ارتباطِ ViewModel با View هست ، نیست) ، باید کارهاش را با
درخواست کردن پیش ببره . یعنی View ، از ViewModel ،
درخواستِ انجامِ کاری را کنه که میخواد روی Model انجام بده تا ViewModel اون کار را براش انجام بده .
1) در حالت اول (این حالت ، Binding کردن را نادیده میگیریم و اصلا نمیخوایم Binding ای انجام بدیم) ، برای ارتباطِ View با ViewModel ، درخواستِ مورد نظرمون را از View به ViewModel میفرستیم تا (بصورت غیر مستقیم) ، ViewModel مون اون درخواست را برای اِعمال تغییرات (روی مقادیر اعضای Model) انجام بده .
حالا این درخواست میتونه توسط متد ، رویداد ، یا Command ها انجام بشه . یعنی شکل زیر :
حالا این درخواست میتونه این طور باشه که مثلا متد یا رویدادی را درونِ ViewModel بنویسه که مثلا آرگومان هایی را از View بگیره (آرگومان هایی که مثلا View با فراخونیِ این متد مشخص کنه که کدوم پروپرتیِ ViewModel و همچنین چه عضوی از این پروپرتی (که این عضو ، همون عضوِ Model هست) ، چه مقدارِ جدیدی بگیره) یا اینکه این درخواست میتونه هر طورِ دیگه باشه . مثلا با ارسال رویداد باشه . حالا با command ها آشنا نیستم اما یه چیزهای سطحی که متوجه شدم ، انگار command ها هم این کار را انجام میدن . یعنی درخواستی را ارسال میکنن که کارشون شبیه رویدادهاست .
یعنی مثلا (اگه نخواستیم از command ها استفاده کنیم ، این طور هم میشه که) این متدِ درونِ ViewModel :
یه ورودی از نوع object بگیره که همون شیِ پروپرتی ای هست که درون ViewModel هست (تا ViewModel بدونه تغییراتی روی اعضای این پروپرتی میخواد اِعمال بشه . مثلِ پروپرتیِ Studentدر کلاس StudentViewModel) .
و همچنین یه ورودی دیگه حالا مثلا از نوعِ رشته که نام پروپرتی ای را بده که جزء اعضای پروپرتیِ که در آرگومان اول داده بودیم و میخواد مقدار اون پروپرتی را تغییر بده ، بده (یعنی مثلا پروپرتیِ FirstName را که میخواد مقدارش را تغییر بده ، نامِ این پروپرتی را بصورت رشته دریافت کنه) و بعد توسط Reflection ، دنبال این پروپرتی ، در شیِ آرگومان اول که داده شد ، بگرده .
و همچنین آرگومان سوم را هم object ای بگیره به عنوان مقدار . یعنی مقدارِ (FirstName ای که در آرگومان دوم بصورت رشته در این متد داده بودیم) را تغییر بده (توسط Reflection) .
یا حالا توسط Command یا هر روش دیگه ای .
2) در حالت دوم (در این حالت هم نمیخوایم Binding ای انجام بدیم) ، اگه ViewModel بخواد با View ارتباط برقرار کنه ، توسط رویداد (و یا هر روش دیگه ای شبیه به این) ، تغییراتی که برای پروپرتی هاش اتفاق افتاد را به View اطلاع رسانی میکنه . یعنی شکلی شبیه زیر (این حالت ، علاوه بر حالت قبل هست . یعنی روش قبلی که ارتباط View با ViewModel بود ، به همون روش قبلی ، سر جاش باقی هست) :
3) حالت سوم ، حالتی هست که Binding ئه یک طرفه هم انجام میدیم . یعنی Binding ای که وقتی پروپرتیِ ViewModel تغییر کرد ، به پروپرتیِ کنترلی در View متصل میشه و اون پروپرتی از کنترل و المنت ، اتوماتیک تغییر میکنه . یعنی در این حالت ، دیگه نیاز به Notification از طرف ViewModel به View دیگه لازم نیست (و Binding این کار را انجام میده) .
همچنین ارتباطِ View با ViewModel ، مثل روشِ حالت اول هست . یعنی :
4) حالت چهارم ، Binding اش برعکسِ حالت قبلی هست . یعنی حالتی هست که Binding ئه یک طرفه اما از طرفِ View به ViewModel انجام میگیره. یعنی Binding ای که وقتی پروپرتیِ المنتی در View تغییر کرد ، به پروپرتیِ ای در ViewModel متصل میشه و اون پروپرتی از ViewModel ، اتوماتیک تغییر میکنه .
در این حالت ، دیگه نیاز به ارسال درخواست از طرف View به ViewModel نیست (و Binding این کار را انجام میده) .
همچنین ارتباطِ View با ViewModel ، مثل روشِ حالت اول هست . یعنی :
5) حالت پنجم هم که Binding ئه دو طرفه هست .
در این حالت ، نه نیازی به ارسال درخواست از طرف View به ViewModel هست و نه نیازی به اطلاع رسانی از طرف ViewModel به View . چون تغییر مقدار و اینها ، اتوماتیک در دو طرف ، در Binding ئه دو طرفه ، انجام میشه .
یعنی شکل زیر :
اینهایی که گفتم ، درست هستند؟
تشکر استاد