the_king
مدیرکل انجمن
چون در کد قبلی خطای زمان کامپایل نداره، خطای که رخ میده زمان اجرا است که اونم باگ در کد شما است، خطای منجر به توقف اجرا نیست.البته نمیدونم کد بالا چرا ارور میده اما کدِ قبلی ، ارور نمیده اما فقط استایلش کار نمیکنه .
چون در کد قبلی خطای زمان کامپایل نداره، خطای که رخ میده زمان اجرا است که اونم باگ در کد شما است، خطای منجر به توقف اجرا نیست.البته نمیدونم کد بالا چرا ارور میده اما کدِ قبلی ، ارور نمیده اما فقط استایلش کار نمیکنه .
ابتدای فایل MainWindow.xaml رو ببینید، توصیف المنت از چه نوعی است؟ شما دارید یک المنت Window رو توصیف می کنید، نه یک المنت از کلاس سفارشی فلان که وارث Window ئه. در Window هم طبیعتا اون مشخصه مورد نظر شما نیست که بهش Binding ای معنی داشته باشه.سلامی مجدد
خیلی ممنون استاد .
استاد ، میگم وقتی در MainWindow مون (در کد سی شارپ) یه پروپرتی ای تعریف کنیم ، چجوری میشه از طریق xaml ، به این پروپرتی ، دسترسی داشت؟
شدنی هست؟
برای Binding کردن به این پروپرتی در کد xaml ، نیاز دارم .
یا اینکه راهی نداره و Binding را باید فقط از طریق کد سی شارپ انجام داد؟
تشکر استاد .
ابتدای فایل MainWindow.xaml رو ببینید، توصیف المنت از چه نوعی است؟ شما دارید یک المنت Window رو توصیف می کنید، نه یک المنت از کلاس سفارشی فلان که وارث Window ئه. در Window هم طبیعتا اون مشخصه مورد نظر شما نیست که بهش Binding ای معنی داشته باشه.
اول یک کلاس دیگه تعریف کنید، فرضا MyWindow که وارث Window باشه، و اون مشخصه مورد نظرتون رو در اون کلاس MyWindow تعریف کنید.
این کلاس جدید برای اینه که بتونه مستقل از xaml ئه کامپایل بشه، وگرنه نمیشه که در حال توصیف xaml برای MainWindow باشید ولی در عین حال از MainWindow که هنوز توصیف اش کامل نشده المنت ایجاد کنید.
بعد بیایید کد MainWindow.xaml رو ویرایش کنید تا بجای المنت Window یک المنت MyWindow رو توصیف کنه.
و در MainWindow.xaml.cs هم بجای وراثت از Window از MyWindow وراثت باشه.
حالا بعد کامپایل، MainWindow.xaml میتونه از اون مشخصه داخل MyWindow به هر شکلی در توصیف المنت MyWindow استفاده کنه، برای Binding و ...
توضیح دادم براتون. شما فرضا المنت MainWindow رو دارید توصیف می کنید، می خواهید بگید این المنت MainWindow تشکیل شده از یکسری اجزاء، فرضا تشکیل شده از یک کلاس Window ای که داخلش فلان اجزاء هست. Window قبلا توصیف شده، کلاس و توصیف اش کامل ئه و حالا می توانید بگید در توصیف MainWindow از Window استفاده شده. اما وقتی MainWindow رو دارید توصیف می کنید خود MainWindow توصیف کامل شده؟ هنوز توصیف نشده، تازه می خواهید توصیفش کنید. نمی توانید بگید که این MainWindow تشکیل شده از یک MainWindow (که خودش تشکیل شده از یک MainWindow، که تشکیل شده از یک MainWindow...) شما هنوز MainWindow رو توصیف نکرده اید، تازه دارید توصیفش می کنید. توصیف که نمیتونه از چیزی که هنوز توصیفش نکردید برای توصیف خودش استفاده کنه.خیلی ممنون استاد .
بله ، متوجه ام .
آها ، خیلی ممنون .
سئوال اینجاست که چرا همه ی این کارها را روی MainWindow نمیشه انجام داد و دوباره کاری کنیم و مجددا از یه کلاس دیگه ارث بری کنیم؟
یعنی چرا نمیشه در خودِ MainWindow.xaml ، اطلاعاتش را ویرایش کنیم تا بجای المنت Window ، از المنت MainWindow استفاده و توصیف کنه؟
ربطی بهم ندارند، مستقل هستند. کامپایل فایل سی شارپ کاری به xaml نداره. اما طبعا در xaml اگر ارجاعی به یک کلاس باشه برای تفسیر اون ارجاع نیاز به کامپایل اون کلاس هست. توضیح بالا رو بخونید، صحبت سر توصیف در xaml ئه، xaml داره چیزی رو توصیف می کنه که هنوز توصیف نشده، نمیشه که توصیف اش وابسته به خودش باشه که داره توصیف میشه. MainWindow چیست؟ MainWindow تشکیل شده از یک MainWindow است که به آن MainWindow می گویند. این چه توصیفی ئه؟البته جواب تون در اون خط ای که بولد کردم ، هست ؛ اما من دقیق متوجه نشدم .
الان اون خطی که گفتید ، یعنی برای کمپایلِ فایل سی شارپِ و کلاسِ MainWindow.xaml.cs ، به xaml نیاز هست اما برای کمپایلِ اجدادش (و اون نوعی که در تگِ xaml که بصورت پیش فرض ، نوعِ Window هست) ، نیاز به xaml نیست؟
کلا درباره ی اون خط بیشتر توضیح میدین؟
نمیدونم دارید چیکار می کنید ولی اگر نوع یک مشخصه <Collection<T باشه، xaml میتونه بصورت خودکار از InsertItem اش استفاده کنه و بهش عضو اضافه کنه. حالا بعدا می توانید اعضاء مجموعه رو جایی به عنوان فرزند اضافه کنید.مثلا نمیشه (یا نمیدونم) که در کلاس فرزند (فرضا در MainWindow) ، چجوری در xaml ، کنترل های مورد نظرم را به عنوانِ Children در این پروپرتیِ DockPanel اضافه کنم .
یا اینکه در کلاس فرزند (فرضا در MainWindow) ، در xaml اش نمیشه بدون اینکه به پروپرتی ای در xaml مقدار بدیم ، بریم و مستقیما به اعضای اون پروپرتی مقدار بدیم .
اگر درست متوجه شده باشم شما یکجا چیزی رو به عنوان Content فلان چیز تعریف می کنید، بعد میایید در جای دیگری برای Content همون مورد توصیف می نویسید، طبیعتا این توصیف تون به معنای جایگزینی مقدار قبلی مشخصه است.یا اینکه با اضافه کردنِ کنترلی در xaml ، اون اشیایی که در پنجره ی والد در کد سی شارپ (در PoshtibangirToloWindowBase) نوشته بودم ، اتوماتیک زمان اجرا محو میشد .
قاعدتا باید مجزا باشند. اگر دنبال این هستید که یک ظاهر در XAML توصیف کنید و بعد با وراثت در XAML های متفاوتی تغییرش بدهید و تکمیلش کنید، همچین چیزی شبیه به وراثت بصری در WPF نیست.نهایتا اینکه برای این قضیه (زمانی که بعضی از کنترل ها ، در چند ویندوز مشترک هستن و ویندوزِ پدر هم داریم) ، راه حلی دارین یا اینکه همون روش قبلی را پیش برم و همه ی کنترل های مشترک را در هر ویندوزِ فرزند ، جداگانه ایجاد کنم؟
ساختن UserControl برای مواقعی که میخواهید یک جزء با ساختاری رو در جاهای متفاوتی تکثیر کنید مناسبه، ولی ظاهرا شما دنبال وراثت هستید، نه تکثیر.یا فرضا روش ایجاد user control را پیشنهاد میکنین؟
نمیدونم دارید چیکار می کنید ولی اگر نوع یک مشخصه <Collection<T باشه، xaml میتونه بصورت خودکار از InsertItem اش استفاده کنه و بهش عضو اضافه کنه. حالا بعدا می توانید اعضاء مجموعه رو جایی به عنوان فرزند اضافه کنید.
%%ItemTitle%% | %%ProjectTitle%%
www.grapecity.com
اگر درست متوجه شده باشم شما یکجا چیزی رو به عنوان Content فلان چیز تعریف می کنید، بعد میایید در جای دیگری برای Content همون مورد توصیف می نویسید، طبیعتا این توصیف تون به معنای جایگزینی مقدار قبلی مشخصه است.
قاعدتا باید مجزا باشند. اگر دنبال این هستید که یک ظاهر در XAML توصیف کنید و بعد با وراثت در XAML های متفاوتی تغییرش بدهید و تکمیلش کنید، همچین چیزی شبیه به وراثت بصری در WPF نیست.
ساختن UserControl برای مواقعی که میخواهید یک جزء با ساختاری رو در جاهای متفاوتی تکثیر کنید مناسبه، ولی ظاهرا شما دنبال وراثت هستید، نه تکثیر.
خیلی ممنون استاد .
منم میخوام یه جزیی از کنترل ها را در همه ی ویندوزهام باشن دیگه .
یعنی توی همه ی ویندوزها ، DockPanel وجود داشته باشه منتها توی هر ویندوز در فرزند ، بشه یه کنترلِ متفاوتی را به این DockPanel اضافه کرد .(در پست قبلی ، کاملتر توضیح داده بودم) .
پیشنهادتون چیه؟
تشکر استاد .
من پیشنهادی ندارم. WPF تکنولوژی جدیدی نیست، به قدر کافی آزموده شده. ببینید تا الان چه چیزهایی هست، آنچه که هست به چه شکل طراحی شده اند، شما هم با همون روال ها پیش می روید. طبعا در عرض سیزده چهارده سال هر روش مقبولی که میتونست باشه پیاده شده. بهتره شیوه طراحی خودتون رو باید با آن چیزی که هست مطابقت بدهید، نه اینکه اول یک روش جدیدی در ذهنتون در نظر بگیرید و بعد دنبال راهی برای پیاده سازی اش باشید.پیشنهادتون همونه که با روش قبلی برم؟
یعنی در هر کدوم از ویندوزِ فرزندانش (مثل MainWindow و ...) ، جداگانه اون DockPanel را ایجاد کنم؟
که در این صورت ، کدها تکرار میشن .
یعنی تکرار کدها (روش قبلی) را پیشنهاد میکنین؟
ایجاد user control در اینجا ، کاربرد نداره؟
من پیشنهادی ندارم. WPF تکنولوژی جدیدی نیست، به قدر کافی آزموده شده. ببینید تا الان چه چیزهایی هست، آنچه که هست به چه شکل طراحی شده اند، شما هم با همون روال ها پیش می روید. طبعا در عرض سیزده چهارده سال هر روش مقبولی که میتونست باشه پیاده شده. بهتره شیوه طراحی خودتون رو باید با آن چیزی که هست مطابقت بدهید، نه اینکه اول یک روش جدیدی در ذهنتون در نظر بگیرید و بعد دنبال راهی برای پیاده سازی اش باشید.
اول باید ببینید در WPF به چه روشی طراحی می کنند، اگر تا به حال پروژه های کمی رو بررسی کرده اید، برای پیدا کردن راهکار ها مرتب به مشکل برخورد می کنید.
خیلی ممنون استاد .
الان user control به درد جایی میخوره که در چندین Window ، بخوایم ازش استفاده کنیم اما در عین حال ، حداقل در کدهای xaml (در Window ای که از اون user control استفاده میکنیم) ، نخوایم کنترلی به user control مون اضافه کنیم .
اما اگه در کدهای سی شارپ خواستیم به user control ، کنترلی را اضافه کنیم ، مشکلی نیست .
اینهایی که گفتم، درسته؟
تشکر استاد .
ContentProperty صرفا نقش خلاصه ساز رو داره، یک مشخصه ای رو تعیین می کنه که بدون نیاز به صریح وارد کردنش بشه بهش مقدار داد.سلامی مجدد
انگار جواب حدودی اش اینه که برای اینکار ، یه کلاسی بسازیم که از UserControl ارث بری کنه و یه DependencyProperty ای براش تعریف کنیم و نکته ی مهم اش اینه که برای این کلاس ، اتریباتسِ ContentProperty را برای اون پروپرتی در نظر بگیریم و بعد هم ازش در Window (در xaml) استفاده کنیم (که البته گفتش راه کاملا مناسبی شاید نباشه) :
How to instantiate UserControl and add Items to its Container in XAML
I have the following UserControl: <UserControl x:Class="UserControlTest.UserControl" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.stackoverflow.com
و
Child container in WPF User Control
social.msdn.microsoft.com
تشکر استاد .
<ContentControl>
<ContentControl.Content>
<Grid>
<Button/>
</Grid>
</ContentControl.Content>
</ContentControl>
<ContentControl>
<Grid>
<Button/>
</Grid>
</ContentControl>
ContentProperty صرفا نقش خلاصه ساز رو داره، یک مشخصه ای رو تعیین می کنه که بدون نیاز به صریح وارد کردنش بشه بهش مقدار داد.
ContentProperty جزئی از حل یک مساله نیست چون اگر نباشه هم اتفاقی نمی افته.
فرضا ContentProperty این امکان رو میده که بجای اینکه بنویسید :
بتوانید خلاصه تر بنویسید :XML:<ContentControl> <ContentControl.Content> <Grid> <Button/> </Grid> </ContentControl.Content> </ContentControl>
چون در صفات اون کلاس [ContentProperty("Content")] نوشته شده.XML:<ContentControl> <Grid> <Button/> </Grid> </ContentControl>
یعنی چیزی که به عنوان محتوا بین تگ آغازین و پایانی المنت و بدون مشخص کردن مشخصه خاصی می نویسید رو به عنوان مقدار فلان مشخصه فرض کنه. وگرنه ContentProperty نقش مهمی در اضافه کردن فرزندان و ... نداره.
عرض کردم، پیشنهادی ندارم.به نظرتون این روش را در پروژه اجرا کنم یا همون روش قبلی که کدها را کپی میکردم؟
شما بودید ، کدوم روش را انتخاب میکردید؟
عرض کردم، پیشنهادی ندارم.
public partial class BaseControl : UserControl
{
public UIElementCollection NewControls
{
get { return (UIElementCollection)GetValue(NewControlsProperty); }
set { SetValue(NewControlsProperty, value); }
}
public static readonly DependencyProperty NewControlsProperty = DependencyProperty.Register("NewControls", typeof(UIElementCollection), typeof(BaseControl));
public BaseControl()
{
InitializeComponent();
this.NewControls = new UIElementCollection(this, this);
this.Loaded += BaseControl_Loaded;
}
void BaseControl_Loaded(object sender, RoutedEventArgs e)
{
foreach (UIElement element in NewControls.Cast<UIElement>().ToList())
{
NewControls.Remove(element);
this.newPanel.Children.Add(element);
}
}
}
foreach (UIElement element in NewControls.Cast<UIElement>().ToList())
foreach (UIElement element in NewControls)
System.InvalidOperationException: 'The enumerator is not valid because the collection changed.'
foreach (UIElement addControl in NewControls.Cast<UIElement>())
NewControls.Remove(element);
this.newPanel.Children.Add(element);
System.InvalidOperationException: 'Specified element is already the logical child of another element. Disconnect it first.'
اول بد نیست یک نگاهی به ساختار IEnumerator بندازید، از ساختارش هم می توانید متوجه بشوید که به چه دلیل اینطوریه، ولی چیزی که میخواهم بهش توجه کنید اینه:خیلی ممنون استاد .
تصمیم گرفتم که از طریق ساختن user control انجام بدم .
استاد ، در همون لینک ، یعنی در لینک زیر ، جواب اولی :
How to instantiate UserControl and add Items to its Container in XAML
I have the following UserControl: <UserControl x:Class="UserControlTest.UserControl" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.stackoverflow.com
یعنی در کد زیر :
C#:public partial class BaseControl : UserControl { public UIElementCollection NewControls { get { return (UIElementCollection)GetValue(NewControlsProperty); } set { SetValue(NewControlsProperty, value); } } public static readonly DependencyProperty NewControlsProperty = DependencyProperty.Register("NewControls", typeof(UIElementCollection), typeof(BaseControl)); public BaseControl() { InitializeComponent(); this.NewControls = new UIElementCollection(this, this); this.Loaded += BaseControl_Loaded; } void BaseControl_Loaded(object sender, RoutedEventArgs e) { foreach (UIElement element in NewControls.Cast<UIElement>().ToList()) { NewControls.Remove(element); this.newPanel.Children.Add(element); } } }
یعنی اگر foreach داره اعضاء فلان مجموعه رو یکی یکی تحویل میده، در این لحظه Enumerator فقط میدونه عضو Current چیه و میتونه از رویش با MoveNext عضو بعدی رو پیدا کنه و اگر این وسط بخواهید تغییری در مجموعه بدهید، حساب و کتاب Enumerator رو می زنید بهم و برای همین نباید مادامی که با اون Enumerator کار می کنید تغییری در مجموعه بدهید.Enumerators can be used to read the data in the collection, but they cannot be used to modify the underlying collection.
چون داخل foreach داره مجموعه NewControls رو ویرایش می کنه، پس در foreach خود NewControls رو نباید پیمایش کنه، میاد ازش یک کپی بصورت List میگیره و اون List رو پیمایش می کنه، نه خود NewControls رو. و طبعا حذف کردن اعضاء NewControls داخل حلقه تاثیری روی اون List نداره. سوالات بعدی تون هم مربوط به همون قضیه است.1 - چرا وقتی میخواست حلقه ی foreach بنویسه ، به این صورت نوشت؟ :
C#:foreach (UIElement element in NewControls.Cast<UIElement>().ToList())
به این دردش میخوره که تو کلاس UIElementCollection لازمشون داره و ازشون استفاده می کنه.2 - در پارامترهای متد سازنده ی UIElementCollection ، منظور از visualParent ، همون والد در VisualTree هست و همچنین منظور از logicalParent ، والد در LogicalTree هست؟
خوب فرضا هم که اینها را در این کلاس گرفت ؛ چه به دردش میخوره؟
public virtual int Count => _visualChildren.Count;
Collection ها یعنی کلاس هایی که همه شون یک ویژگی مشترک دارند که اونم پیاده سازی ICollection ئه. فقط همین. یعنی رفتارشون میتونه کاملا متفاوت از هم باشه. ICollection تعیین نمیکنه که کلاس چیکار بکنه یا نکنه.مگه در کالکشن ها که رابطه ی درخت ها را مشخص میکنن؟ وقتی که کنترلی ، به والدی اضافه شد ، اون وقت مشخص نمیکنن؟
چون کارکرد شیء کلاس UIElementCollection وابسته به وجود اون دو پارامتر ئه. بدون اونها کارکردی نداره. همانطور که کارکرد کلاس FileInfo وابسته به یک فایل مشخص ئه، اگر اون فایل به عنوان پارامتر ورودی مشخص نشه که کارکرد شیء FileInfo معنی نداره.کلا چرا لازمه این دو پارامتر ، در این متد سازنده مشخص بشه؟
در WPF دو مفهوم هست که قبلا در موردشون صحبت کرده ایم، Logical Tree و Visual Tree.و همچنین وقتی میگیم که شیِ UserControl مون ، والد بصری (visualParent) ئه کنترل هایی هست که درون کالشنِ NewControls اضافه میشه ، دقیقا یعنی چه و همچنین باز وقتی میگیم که شیِ UserControl مون ، والد منطقیِ (logicalParent) ئه کنترل هایی هست که درون کالشنِ NewControls اضافه میشه ، دقیقا یعنی چه؟
اول بد نیست یک نگاهی به ساختار IEnumerator بندازید، از ساختارش هم می توانید متوجه بشوید که به چه دلیل اینطوریه، ولی چیزی که میخواهم بهش توجه کنید اینه:
یعنی اگر foreach داره اعضاء فلان مجموعه رو یکی یکی تحویل میده، در این لحظه Enumerator فقط میدونه عضو Current چیه و میتونه از رویش با MoveNext عضو بعدی رو پیدا کنه و اگر این وسط بخواهید تغییری در مجموعه بدهید، حساب و کتاب Enumerator رو می زنید بهم و برای همین نباید مادامی که با اون Enumerator کار می کنید تغییری در مجموعه بدهید.
Enumerator فقط میتونه ریست بشه و از اول دوبار اعضاء رو بشماره.
نتیجه اینکه داخل foreach مجاز به تغییر در مجموعه نیستید، چرا؟ چون Enumerator ئه فقط تا زمانی اعتبار داره که مجموعه دست نخورده است، به محض ویرایش از اعتبار می افته، باید Enumerator جدیدی ایجاد بشه که با منطق foreach جور در نمیاد، نمیشه که foreach قبلی نیمه کاره ول بشه و از آیتم اول foreach دوباره شروع به کار کنه.
چون داخل foreach داره مجموعه NewControls رو ویرایش می کنه، پس در foreach خود NewControls رو نباید پیمایش کنه، میاد ازش یک کپی بصورت List میگیره و اون List رو پیمایش می کنه، نه خود NewControls رو. و طبعا حذف کردن اعضاء NewControls داخل حلقه تاثیری روی اون List نداره. سوالات بعدی تون هم مربوط به همون قضیه است.
foreach (UIElement element in NewControls.Cast<UIElement>())
این شیء ای که از نوع <Enumerable<UIElement بر میگردونه، چی به foreach تحویل میده؟ طبق توضیحات foreach با GetEnumerator اش یک IEnumerator تحویل میده. حالا این IEnumerator منبع اش کدوم مجموعه است؟ خودش مستقلا یک مجموعه داخلش داره و اعضاء خودش رو بر میگردونه؟ یا <Enumerable<UIElement ئه یک مجموعه کپی از روی NewControls برای خودش ایجاد کرده و اعضاء اون رو بر می گردونه؟ یا مستقیما اعضاء NewControls رو بر میگردونه؟خیلی ممنون استاد .
همینطور بخاطر جواب بقیه ی قسمت ها .
حالا من دقیق متوجه نشدم که چرا کد زیر هم همون ارور را میده؟ :
C#:foreach (UIElement element in NewControls.Cast<UIElement>())
متد Cast<UIElement>() که شی ای از Enumerable<UIElement> را برمیگردونه . یعنی همون شیِ NewControls (که UIElementCollection) باشه ، نیست .
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 هاشون ربطی نداره.بنابراین خروجی این متدِ Cast<UIElement>() که شیِ Enumerable<UIElement> هست ، مثلِ متدِ ToList<UIElement>() که شیِ List<UIElement> هست ، شی ای متفاوت از نوع UIElementCollection هست دیگه .
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();
}
}
var b = new B();
foreach (var i in b)
{
A.Source.Sort();
}
اولا شما دارید یک Model ای رو توصیف می کنید که واسط پیچیده ای داره، طراحی بدی داره. ساختار داده داخلش به خودش مربوط ئه، ممکنه هزار تا کلاس داخل خودش استفاده کنه که private باشند، ایرادی نداره، اما واسطی که به محیط خارج از خودش ارائه میکنه نباید دردسر ساز باشه، نباید زیادی پیچیده باشه. اگر Model طراحی خوبی داشته باشه نباید برای تعامل با ViewModel بار زیادی روی دوش ViewModel بندازه.استاد ، در قضیه ی MVVM :
1 - فرض کنید در همون کلاس Student ، دو تا پروپرتی ای داشتیم از نوع کلاس های A و B .
که همه ی این کلاس ها را درون Model مون تعریف کرده باشیم .
هر کدوم از این کلاسِ A و B ، باز خودشون پروپرتی های بسیار زیادتری داشته باشن از نوع کلاس های دیگه ای که باز درون Model مون تعریف کرده باشیم .
حالا اگه بخوایم به این پروپرتی ها مقدار بدیم ، باید یه متد داخل ViewModel مون بسازیم که پارامترهایی از نوعی داشته باشه که از نوعِ کلاسی که در Model مون تعریف شده (صریحا) به حساب نیاد .
این Model طراحی بدی داره.نمیدونم منظورم را متوجه شدین یا نه .
اما اگه این کار را کنیم ، در کلاس ها(ی پیچیده و تو در تویی که در Model تعریف کنیم) ، کار مقداردهی به اعضای یک کلاس Model ، خیلی پیچیده میشه .
در مطالب قبلی صحبتش شده. وظیفه هر جزء رو در حد مسئولیت خودش در نظر بگیرید، یعنی فرضا اگر Model قراره موقع تغییر اطلاع بده، مسئولیتش در همین حد ئه که امکانی به ViewModel یا کلا هر موجودیت خارج از خودش بده که اگر خواست، بتونه از تغییر مطلع بشه، فقط همین. اینکه ViewModel به تغییر اهمیت میده یا نمیده، به View خبر میده یا نمیده یا چطور خبر میده به Model ربطی نداره.2 - فرض کنید مقدار پروپرتی ای در Model را از دیتابیس گرفتیم و پُر کردیم .
اگه از View ، عمل Binding ای به این پروپرتی در Model انجام داده باشیم ، که هیچ (که اغلب ، همین طوره) .
اما اگه Binding انجام نداده باشیم و بخوایم توسط ViewModel ، این تغییرات را به View مون اطلاع بدیم ، لازمه که در ViewModel ، یه پروپرتی از نوعِ View مون هم در نظر بگیریم تا توسطش ، به View اطلاع بدیم . درسته؟
نمیدونم سئوال دومی را قبلا پرسیده بودم یا نه .
اون WinForm ای که میگید اسم پلتفرم داخل NET. ئه، طبعا وقتی خود NET Framework. سال 2002 ارائه شده، WinForm هم نمیتونسته زودتر از 2002 باشه، با خود NET. معرفی شده. اما قدمت Windows Forms که ربطی به NET. نداره، قبل از اینکه NET. ارائه بشه برنامه های تحت Windows Forms و زبان های برنامه نویسی ویژوال با پلتفرم Windows Forms بودند. یعنی از همون موقع که ویندوز این واسط کاربری رو داشته زبان های برنامه نویسی ویژوال اون دوران هم همچین پلتفرمی داشته اند.- یک سئوال جنبی اینکه قدمت WinForm واسه سال 2002 هست؟
احتمالا در مورد Windows Forms صحبت می کردم، Windows Forms یک پلتفرم خاص NET. نیست، فرضا در Visual Basic 5 (سال 1997) هم پلتفرم همون Windows Forms ئه.توی ویکی پدیا ، اولین انتشارش را سال 2002 نوشته (چون اگه اشتباه نکنم ، قبلا بیشتر گفته بودین).
بله.قدمت wpf هم واسه سال 2006 هست دیگه. درسته؟