PDA

View Full Version : گفتگو: الگوی MVVM



امید خطیبی
یک شنبه 22 دی 1392, 09:05 صبح
با سلام خدمت دوستان عزیز دوستان من این پست رو اینجا زدم چون ممکنه خیلی از دوستان همین مشکل من رو داشته باشند

و شاید خواسته باشند بدونند توسط الگوی MVVM داخل WPF برنامه نویسی کنند و چون منبع فارسی زیاد نیست دوستان هر سوالی داشتند می توانند در این قسمت بپرسند (البته در رابطه با الگوی MVVM داخل WPF باشه)

اولین سوال رو من از دوستان برنامه نویس می پرسم تا مبتدیان هم یاد بگیرند

دوستان یکی برای من توضیح دهد که من چطور می تونم با زدن یک کلید کار هایی رو انجام بدهم

من این رو می دونم که با استفاده از بایندینگ میشه اینجور کاری کرد (Command Binding & ICommand) اما من یک کار دیگه می خواهم انجام بدهم
اول این هست که هیچ کدی داخل فرم من نباشه
دوم این که با استفاده از آن کلید چطور می تونم فرم دیگری رو نمایش بدهم
سوال اصلی این هست که با استفاده از ICommand من چطوری می توانم فرم دیگری را نمایش بدهم که در پروژه من موجود می باشد.
یا سوال را اشتباه پرسیدم و باید اینجوری بگم که من چطوری می تونم با استفاده از Binding فرم دیگری رو نشون بدهم
با تشکر از دوستان و عزیزان برنامه نویس

m.bibjan
یک شنبه 22 دی 1392, 09:11 صبح
سلام
من متوجه سوالتون نشدم اصلا ؟

امید خطیبی
یک شنبه 22 دی 1392, 09:15 صبح
دوست عزیز من می خواهم با استفاده از یک Button زمانی که روش کلیک کردم یک فرم دیگه رو به نمایش در بیارم با استفاده از Command Binding این کار رو هم انجام بدهم
ولی نمی خوام کدی در پشت ویندوز من نوشته بشه همه این ها رو می خواهم در کلاس ViewModel فرم خودم قرار بدهم

nafisehk
یک شنبه 22 دی 1392, 11:43 صبح
سلام

public RelayCommand ShowBanksDefinitionViewCommand { private set; get; }


public MainViewModel()()
{
ShowBanksDefinitionViewCommand = new RelayCommand(ShowBanksDefinitionViewExecute);

}


public void ShowBanksDefinitionViewExecute()
{
//show
}

البته من با مسنجر notificationmessage میفرستم به view و تو View ویندورو show میکنم.

امید خطیبی
یک شنبه 22 دی 1392, 12:03 عصر
خیلی ممنون دوست عزیز

این کدی رو که نوشتین اینجا من بعضی از مفاهیمش رو میفهمم یعنی همش ولی ...
میشه یک مثال کوچیک بگذارید
در حد یک فرم و یک باتوم و نمایش یک فرم دیگه
خیلی ممنون از شما دوست عزیز

aghayex
یک شنبه 22 دی 1392, 22:28 عصر
شما به وسیله مسنجرها می تونید این کارو بکنید . تو سایت آقای نصیری سری آموزش های سیلورلایت فصل یازدهم در این خصوص توضیح داده .

امید خطیبی
دوشنبه 23 دی 1392, 11:06 صبح
دوستان من زیاد به دنبال این مسئله گشتم اما جوابی که می خواستم و نتیجه ای که می خواستم برام نداشته

ببینید من می خواهم کدهای فرمم را داخل ViewModel که به نام فرم هست بریزم و آن ViewModel به جای CodeBehind فرم من عمل کنه

یه مثالی یک راهنمایی کنید
من کتاب سیلورلایت آقای نصیری را هم دیدم ولی آن چیزی رو که من می خواستم داخلش نبود
یک Sample اگر برای من اینجا بگذارید ممنون می شوم.

امید خطیبی
دوشنبه 23 دی 1392, 16:19 عصر
سلام
دوستان یک سوال دیگه داشتم و آن هم این هست
مقدار RelayCommand چطوری باید این مقدار رو بسازیم و چیه
آخه یکی از دوستان آن بالا گفته و من هم یک مقداری در موردش خواندم
اما چیزی سر در نیوردم.
اگر توضیحی بدهید ممنون می شوم.

امید خطیبی
دوشنبه 23 دی 1392, 17:25 عصر
با سلام خدمت دوستان
دوستان واسه نمایش فرم دوم آمدم این کار را کرده ام

این از کلاس RelayCommand :



public class RelayCommand : ICommand

{

private readonly Action _handler;

private bool _isEnabled;


public RelayCommand(Action handler)

{

_handler = handler;

}

public bool IsEnabled

{
get { return _isEnabled; }

set

{

if (value != _isEnabled)

{

_isEnabled = value;

if (CanExecuteChanged != null)

{

CanExecuteChanged(this, EventArgs.Empty);

}

}

}

}


public bool CanExecute(object parameter)

{

return IsEnabled;

}


public event EventHandler CanExecuteChanged;


public void Execute(object parameter)

{

_handler();

}

}



و این هم از کد ViewModels من



public MainWindowViewModels()
{

ShowUsersWindow = new RelayCommand(ShowUserWindowExecut);

}

public RelayCommand ShowUsersWindow { get; private set; }


public void ShowUserWindowExecut()

{

UsersWindow USW1 = new UsersWindow();

USW1.Show();


}



خوب حالا این درست شده
یعنی العان کامند من رو میشناسه ولی یه مشکل دیگه دارم داخلش و آن هم این هست که
CanExecute این باتون رو من چطوری باید با True قرار بدهم
اگر کمکم کنین ممنون می شوم
و یک سوال دیگه هم این هست که کامندهای دیگه خودم رو هم هیمن طور می تونم تنظیم کنم با این روش یا نه؟

امید خطیبی
دوشنبه 23 دی 1392, 20:22 عصر
با سلام خدمت دوستان
دوستان یک سوال دیگر
من العان تا مقداری آن فرم را نمایش می دهم اما یک سوال دیگر پیش آمده
من چطوری می تونم با استفاده از ViewModel کلاس یوزرم و با استفاده از LINQ مقادیرم رو از TextBox های ویندوزم بگیرم و درج کنم داخل دیتابیسم
من دیتاکانتکس جداولم را یک نمونه از آن ساختم
ولی این که چگونه می توانم به مقادیر فیلدهای جدولم دسترسی داشته باشم و یا مقدار داخل آن فیلد ها بریزم رو نمی دونم
آخه داخل یک اموزش تصویری دیدم که از Table استفاده می کنه ولی این که من زمانی که آن را می سازم
چیزی که در آموزش نشان می دهد این هست که به فیلد های جدول دسترسی داره
اما واسه من چیزی نمیاره
می خواستم بدونم من چطور می تونم با استفاده از ViewModel و زدن کلید Insert یک رکورد جدید ایجاد کنم و مقادیر داخل TextBox های خودم رو بریزم داخل جدول => این کار را بطور مستقیم می خواهم انجام بدهم
مثلا شماره شناسایی دارم که می خواهم به فیلد شماره شناسایی دسترسی داشته باشم و مقدار آن را در فیلد بریزم و ذخیره کنم
آیا این کار امکان داره.

aghayex
سه شنبه 24 دی 1392, 07:57 صبح
دوست عزیز احساس من اینه که شما دچار سردرگمی شدید . اضافه کردن چه در حالت کد نویسی معمولی و چه در این روش تفاوت زیادی نداره . یه توصیه می کنم و اون اینه که شما به صورت معمولی کد نویسی کنید بهتره اینو گفتم به خاطر :
1 - این روش کد نویسی برای پروژه های بزرگ هست و برای پروژه های کوچیک چیز بی معنی هست و حتی باعث پیچیدگی برنامتون میشه .
2 - این نوع روش کد نویسی برای کار تیمی هست به این صورت که یک نفر کد می زنه , یک نفر طراحی می کنه و ...
3 - این نوع روش کد نویسی برای افرادی مناسب هست که اطلاعات خوبی در خصوص مفاهیم شی گرا دارند .

.

در خصوص مشکل شما آموزش سیلورلایت آقای نصیری کاملا جواب میده ولی باید با دقت بخونیش .
مراحل اجرای یک دستور در روش mvvm به این صورت هست که شما در زملتون یک دکمه دارید میای به جای استفاده از رویداد کلیک دکمه از دستور کامند استفاده می کنی

<button command="{binding btSave}"/>

حالا در ویومدلتون در خود کلاس یه دستور RelayCommand به صورت عمومی تعریف می کنی

public RelayCommand btsave{get;set;}


داخل سازنده کلاستون میاید دستور RelayCommand رو تکمیلتر می کنید

public class viewmodel1
{
public RelayCommand btsave{get;set;}

public viewmodel1()
{
btsave =new RelayCommand (save);
}
}

حالا یه تابع می سازی که نامش save باشه و در اینجا کار تموم شد و وقتی که دکمه رو فشار بدی کلاس save اجرا میشه

امید خطیبی
سه شنبه 24 دی 1392, 10:44 صبح
با سلام خدمت دوست عزیز
داداش من این ها رو فهمیدم و همه این ها رو انجام دادم ولی کاری که من دارم می کنم همچین یه مقدار برنامه بزرگ میاد
چون حدود 16 جدول دارم که نمی دونم چطور باید اینها رو تک به تک کد نویسی کنم و ارتباطش رو با برنامه درست کنم و برای هر قسمتش کد نویسی کنم

"آخه من مگه دارم شروع نمی کنم خوب از این برنامه شروع کنم" => خیلی از افراد هستند که به خاطر همین حرف ها دست به برنامه نویسی نمی زنند

العان مشکل من کار با لینک در برنامه هست و نوشتن همون تابع save هست در برنامه

داخل یکی از پست هام هم نوشتم که همینجا زدم

می تونین به من بگین که من باید چی کار کنم واسه این موارد زیر با استفاده از LINQ
1- می خواهم درج اطلاعات داشته باشم
2-ویرایش کنم
3-حذف کنم
و...
من کار هایی را که شما گفتین همه اینها رو انجام دادم و نوشتم
العان مشکل من با تابع های برنامه هست و کار با LINQ
البته این رو بگم که تا اینجا پیش رفتم که جدول خودم رو داخل دیتای خودم می بینم
ولی این که چطور اطلاعات داخل فیلد هاش بریزم رو نفهمیدم
آخه از Table استفاده می کنه که داخل فیلم اموزشی فیلد های جدول رو دسترسی بهش داره
اما من زمانی که Table رو می نویسم و یک نمونه ازش می سازم فیلد های من رو نمیاره علتش رو نمی دونم.
و یک چیز دیگه هم که هست با استفاده از صفحه LOGIN می خواهم کاری کنم که سطح دسترسی به برنامه معلوم بشه.

امید خطیبی
سه شنبه 24 دی 1392, 12:20 عصر
با سلام خدمت دوستان عزیز و گرامی

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



public UsersWindowViewModel()

{

AddUser = new RelayCommand(ButtonAddUsers_Click);

}

public RelayCommand AddUser { get; private set; }

public void ButtonAddUsers_Click()

{

UsersWindow CONS = new UsersWindow();

var dbusers = new BaskoolEmadDataClassesDataContext();

TUser TUS = new TUser

{

IdUser = int.Parse(CONS.TextIdUser.Text),

NameUser = CONS.TextNameUser.Text + " " + CONS.TextFamilyUser.Text,

Password = CONS.TextPasswordUser.Text,

};

dbusers.TUsers.InsertOnSubmit(TUS);

dbusers.SubmitChanges();

}


چون آخه یک مشکل هست و آن هم اینه که برنامه خطا نداره ولی زمانی که کلیک می کنم روی باتون به تعریف TUsers من گیر میده و نمونه من و کلا خطای زمان کامپایل میگیره آن قسمت رو
راهنمایی کنید این کد بالا اگر چیزی کم و زیاد داره من درستش کنم.

aghayex
سه شنبه 24 دی 1392, 15:21 عصر
باز هم میگم شما ذهنتون مخشوش شده .
ابتدا صبر داشته باش .
دوم مطالعه داشته باش به خصوص سایت آقای نصیری
سوم با یه استاد همیشه در ارتباط باش (مثل خودم که استادمو کچل کردم خودش میدونه منظورم با کیه :لبخندساده:)
چهارم از تکنولوژی های به روز استفاه کن (مثلا برا ارتباط با دیتابیس از ef) استفاده کن
پنجم متناسب با علمت سطح توقعاتت رو در برنامه هماهنگ کن (مثلا شما هنون در درج و ویرایش و حف ابهام داری و از اون طرف دنبال سطح دسترسی در برنامت هستی)

امید خطیبی
سه شنبه 24 دی 1392, 18:35 عصر
باز هم سلام
خوب دوست عزیز من هم واسه همین این پست رو زدم
حرف اولی رو که زدین "ابتدا صبر داشته باش" => من مشتاق یاد گیری هر چه سریعتر این نوع برنامه نویسی هستم
دوم این که برای کم کردن زمان یاد گیری به اینجا مراجعه کردم => علت این که چون دوستان برنامه نویس زیادی در اینجا وجود دارند و این مطالب رو مطالعه کرده اند و با این الگو کار کرده اند و می توانند یک طرح کلی به من بدهند برای برنامه نویسی
موضوع اول که من می خواهم یک برنامه باسکول بنویسم که در کنار آن یک برنامه حسابداری هم باشه
حالا اولین کاری که انجام دادم بانک این برنامه را درست کردم و مواردی رو که می خواستم برای ورودی و خروجی اطلاعاتم داخل بانکم موجود هست
و العان می خواهم برنامه را بنویسم که شامل فرم لاگین برنامه باشه و گرفتن اطلاعات و محاسبات من و ارائه گذارشات من
حالا شما به من میگویید که صبور باش و برو اینجا را مطالعه کن خوب من مواردی رو که گفتین مطالعه کرده ام ولی چیز زیادی از این مطالب نمی فهمم و برای درک بیشتر موضوع من دارم داخل این سایت مشکلاتم رو رفع می کنم که هم اولین برنامه ای باشه که دارم می نویسم و هم به یاد گیری من کمک کنه
و این موضوع رو بگویم که من فعلا نیازی به طراحی آن چنانی برنامه ندارم و فعلا می خواهم بدانم که چگونه می توانم این برنامه را به صورت ساده بنویسم توسط الگوی MVVM تا به دنبال مطالب دیگر بروم
آخه زمانی هم که یک فرد به دنبال یاد گیری هست شماها ذهنش رو مخشوش می کنید و آن فرد نمی داند که باید از کجا شروع به کار کند
حالا که من به شما گفتم هدف من چی هست و چه برنامه ای می خواهم بنویسم به من مراحل کلی کار رو بگین و منابعی را که می توانم آن موضوعات رو داخل آن سایت بیرون بیاورم با ذکر لینکی از آن سایت و منبع
با تشکر از شما دوست عزیز و گرامی

امید خطیبی
دوشنبه 07 بهمن 1392, 18:16 عصر
با سلام خدمت دوستان عزیز
دوستان می توانید مشکل این تکه کد را به من یکی بگه


private void Window_Loaded()
{

Emad.sand.ardakan.DataServices.DataBase._Baskool_E madDataSet _Baskool_EmadDataSet = ((Emad.sand.ardakan.DataServices.DataBase._Baskool _EmadDataSet)(this.UserWindow.FindResource("_Baskool_EmadDataSet")));
// Load data into the table TUser. You can modify this code as needed.
Emad.sand.ardakan.DataServices.DataBase._Baskool_E madDataSetTableAdapters.TUserTableAdapter _Baskool_EmadDataSetTUserTableAdapter = new Emad.sand.ardakan.DataServices.DataBase._Baskool_E madDataSetTableAdapters.TUserTableAdapter();
_Baskool_EmadDataSetTUserTableAdapter.Fill(_Baskoo l_EmadDataSet.TUser);
System.Windows.Data.CollectionViewSource tUserViewSource = ((System.Windows.Data.CollectionViewSource)(this.U serWindow.FindResource("tUserViewSource")));
tUserViewSource.View.MoveCurrentToFirst();
}


this.UserWindow
یک نمونه از View من هست که اطلاعات یوزر من رو به نمایش در میاره
حالا مشکل کجاست این قسمت که به این قسمت گیر میده داخل UsersWindow.xaml.cs
;()InitializeComponent
اگر کمک کنید ممنون می شوم.

kc1860
دوشنبه 07 بهمن 1392, 22:47 عصر
سلام
1. من پاسخ سوال شما رو نمیدونم، اما InitializeComponent در تابع Main اجرا میشه و پس از اجرای تابع Main و لود شدن ویندو، تابع Window_Loaded اجرا خواهد شد. بنابراین اگر شما پیغام خطا رو در قسمت Initialize میگیرید، قاعدتا هنوز ویندو لود نشده تا مشکلات احتمالی Window_Loaded بخواد بررسی بشه.
2. در ضمن نکته ی دیگه اینکه چرا از breakpoint و step کردن توی کد استفاده نمیکنید تا هم خطا برای خودتون مفهوم تر باشه و هم دوستان دیگه بتونن بهتر به شما کمک کنن.

ویرایش: شرمنده من دقت نکردم که تابع window_loaded رو خودتون نوشتین! تصورم این بود که متعلق به window loaded event هستش. اگر تصور اولیه ام اشتباه بوده، فقط بخش دوم پاسخم رو در نظر بگیرید.

امید خطیبی
سه شنبه 08 بهمن 1392, 11:35 صبح
سلامی دوباره
دوست عزیز من این موردی که شما می گویید قبول دارم
اما مشکل اینجاست که زمانی که ویندوز می خواد Load بشه StackOverFlow می شه و به InitializeComponent من گیر میده
کد را هم به هر صورت که بگویید تغییر داده ام اما باز هم کار نمی کنه
و یک موضوع دیگه این هست که من زمانی که کد را به این صورت تغییر می دهم کار می کنه
همون کد بالا رو ببرید داخل Loded ویندوز و داخل codeBehind ویندوز و این گونه میشه

this.FindResource("_Baskool_EmadDataSet")

و اون خط سوم هم به این صورت تغییر می دم درست میشه
حالا من اگر خواسته باشم این رو ببرم داخل ViewModel برنامه و Loaded ویندوز رو ببرم اونجا چطور می تونم این this.FindResource رو اونجا بزرم که خطا هم نده

امید خطیبی
سه شنبه 08 بهمن 1392, 17:16 عصر
از دوستان کسی نمی دونه من چطوری می تونم این کدها را به جای این که داخل Load ویندوزم بنویسم داخل ViewModel برنامه خودم بنویسم

امید خطیبی
چهارشنبه 09 بهمن 1392, 11:44 صبح
شرمنده دوستان عزیز
کسی جواب من رو نداد و خودم به جواب رسیدم حالا اگر شما می خواهید همین تکه کد بالا را در ViewModel برنامه بنویسید از کد زیر استفاده کنید


Emad.sand.ardakan.DataServices.DataBase._Baskool_E madDataSet _Baskool_EmadDataSet = new Emad.sand.ardakan.DataServices.DataBase._Baskool_E madDataSet();


و این خط را هم همین طور


System.Windows.Data.CollectionViewSource tUserViewSource = new System.Windows.Data.CollectionViewSource();


و در لود ویندوز باید تابع داخل ViewModel را فراخوانی کنیم

یک نمونه از viewmodel می سازید و تابع را در لود ویندوز فراخوانی می کنید.

حالا اگر جواب دادن این سوال به من سخت بود نمی دونم که بعد از این همه بازدید از این پست هیچ کس جواب من رو نداد