PDA

View Full Version : مقاله: RIATasks: یک مثال ساده از CRUD در Silverlight-قسمت اول



piroozman
چهارشنبه 15 خرداد 1392, 11:55 صبح
قسمت اول:

http://www.codeproject.com/KB/silverlight/RIATasks/img32.jpg
دلیل نوشتن این فایل آموزشی این بود که می دیدم دوستان(من الجمله خودم) در رابطه با موضوع این مقاله مشکل داشته و منبع مناسبی (حداقل فارسی) برای این موضوع پیدا نمی کنند. برخی دوستان مطمئناً وقت زیادی را برای آموزش Silverlight سپری کرده اند اما همه می دانیم که کتابهای آموزشی به طور مفصل و عملی این روش ها را آموزش نمی دهند (حداقل من ندیدم) و برای آموزش قدم به قدم آن نیز نیاز به زمان زیادی هست. پس ما یک میانبر برای شما ایجاد کرده ایم.
در ضمن در این مقاله روش استفاده از View Model نیز آموزش داده شده است و من اعتقاد دارم که استفاده از این روش مقدار کد نویسی شما را تا حد زیادی کاهش می دهد (که احتمالا شما انتظار آن را نداشتید) (هر چند به نظر می رسد پیچیدگی برنامه زیاد می شود). ولی به بنده اعتماد کنید. اجازه دهید که شروع کنیم:

http://www.codeproject.com/KB/silverlight/RIATasks/img11.jpg
در خصوص CRUDمطمئناً Silverlight متفاوت است زیرا آن با وب سایتی که آنرا راه اندازی کرده است در ارتباط است و از یک ارتباط ناهمگام استفاده می کند. بنابراین آموزش برنامه ای کاربردی از این دست می تواند کمی چالش برانگیز باشد.
بنا براین من یک مثال از نوع end-to-end مطرح می کنم که اهداف زیر را شامل می شود:


Create, Read, Update, Delete رکورد ها از دیتابیس
پیاده سازی فرمهای مبتنی بر امنیت
پیاده سازی امنیت Granular (تنها کاربر User One می تواند ببیند، ویرایش کند و Task های خود را ایجاد کند).
پیاده سازی روش View Model

شیوه View Model


http://www.codeproject.com/KB/silverlight/RIATasks/img16.jpg
روش View Model به یک برنامه نویس اجازه می دهد برنامه ای را ایجاد کند که به طور مطلق به صورت UI ( User Interface) نباشد.
برنامه نویسی که فقط View Model و Model ایجاد می کند با طراحی که تسلط کافی در برنامه نویسی ندارد قادر خواهند بود در تولید برنامه های Silverlight با یکدیگر همکاری کامل داشته باشند.
برنامه کاربردی


http://www.codeproject.com/KB/silverlight/RIATasks/imgB.jpg
ابتدا نگاهی به برنامه بیاندازیم
http://www.codeproject.com/KB/silverlight/RIATasks/img16.gif
وقتی شما به برنامه را اجرا می کنید شما به صورت Logged Out به برنامه ورود پیدا خواهید کرد. شما می توانید با باز کردن کمبوباکس می توانید به عنوان User One یا User Two به برنامه ورود پیدا کنید.
http://www.codeproject.com/KB/silverlight/RIATasks/img18.jpg
با کلیک کردن روی Add می توانید یک وظیفه جدید را ایجاد کنید.
http://www.codeproject.com/KB/silverlight/RIATasks/img19.jpg
با کلیک بر روی Update وظیفه ذخیره خواهد شد.
http://www.codeproject.com/KB/silverlight/RIATasks/img1A.jpg

با انتخاب هر یک از Task ها مشخصات Task انتخاب شده به کاربر نمایش داده می شود و با کلیک بر روی دکمه Update تمامی تغییرات ذخیره می شوند و کلیک بر روی Delete منجر به حذف Taskانتخاب شده خواهد شد.
در قسمت دوم در خصوص نحوه ایجاد برنامه کاربردی صحبت خواهیم کرد.
اصل مقاله (http://www.codeproject.com/Articles/90071/RIATasks-A-Simple-Silverlight-CRUD-Example-using-V)

piroozman
چهارشنبه 15 خرداد 1392, 12:03 عصر
قسمت دوم:
ساخت برنامه
شما برای ایجاد برنامه به نرم افزارهای زیر احتیاج دارید:



Visual Studio 2010 یا بالاتر
Expression Blend 4 یا بالاتر
SQL Server2005 یا بالاتر


تنظیمات مربوط به دیتابیس

http://www.codeproject.com/KB/silverlight/RIATasks/img23.gif

یک دیتابیس جدید تحت RIATasks ایجاد کنید.
http://www.codeproject.com/KB/silverlight/RIATasks/img25.jpg
با استفاده از اسکریپت زیر جدولی با نام Tasks ایجاد کنید:


SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
IF NOT EXISTS (SELECT * FROM sys.objects WHERE object_id =
OBJECT_ID(N"[dbo].[Tasks]") AND type in (N"U"))
BEGIN
CREATE TABLE [dbo].[Tasks](
[TaskID] [int] IDENTITY(1,1) NOT NULL,
[TaskName] [nvarchar](50) NOT NULL,
[TaskDescription] [nvarchar](max) NOT NULL,
[UserID] [int] NOT NULL,
CONSTRAINT [PK_Tasks] PRIMARY KEY CLUSTERED
(
[TaskID] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE =
OFF, IGNORE_DUP_KEY =
OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
END
GO
IF NOT EXISTS (SELECT * FROM sys.indexes WHERE object_id =
OBJECT_ID(N"[dbo].[Tasks]") AND name
= N"IX_Tasks_UserID")
CREATE NONCLUSTERED INDEX [IX_Tasks_UserID] ON [dbo].[Tasks]
(
[UserID] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF,
SORT_IN_TEMPDB = OFF, IGNORE_DUP_KEY = OFF,
DROP_EXISTING = OFF, ONLINE = OFF, ALLOW_ROW_LOCKS = ON,
ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
GO

شما باید تنظیمات امنیتی (Security ) مربوط به SQL را انجام دهید تا در مراحل بعدی برای اتصال به پایگاه داده مشکلی نداشته باشید.
ایجاد یک پروژه Web Application
http://www.codeproject.com/KB/silverlight/RIATasks/img2B.jpg

در VS2010 از منوی File بر روی گزینه New Project کلیک کنید.
http://www.codeproject.com/KB/silverlight/RIATasks/img2C.jpg
یک برنامه Silverlight Application ایجاد کنید
http://www.codeproject.com/KB/silverlight/RIATasks/img2D.jpg
مقادیر پیش فرض را پذیرفته و روی OK کلیک کنید.
http://www.codeproject.com/KB/silverlight/RIATasks/img2F.jpg
پروژه ایجاد خواهد شد.
فعال سازی Form Authentication
در اینجا نیاز هستش که برنامه تحت وب از حالت Form Authentication استفاده کند. وقتی کاربر Login می کند یک authentication ‘token’ رمزگذاری شده در Web Browser کاربر ایجاد می شود که حاوی UseID است.این token (نشانه) به وسیله برنامه Silverlight وقتی که Web service را ایجاد می کند فراخوانی می شود. متدهای web service (در ادامه آنها را ایجاد خواهیم کرد) token را جهت تضمین امنیت بررسی خواهند کرد.
فایل Web.config را باز کنید
http://www.codeproject.com/KB/silverlight/RIATasks/img64.jpg
<authentication mode="Forms"/> را به فایل اضافه کرده آنرا ذخیره کنید و سپس فایل را ببندید.
ساخت صفحه Deafult
http://www.codeproject.com/KB/silverlight/RIATasks/img2.jpg
یک Web Form با نام Default Page به پروژه RIATasks.Web اضافه کنید.
http://www.codeproject.com/KB/silverlight/RIATasks/img9.jpg
فایل RIATasksTestPage.aspx را باز کنید و به Source view سوئیچ کنید.
http://www.codeproject.com/KB/silverlight/RIATasks/img8.jpg
از ابتدای تگ <!DOCTYPE . . . تا انتهای صفحه هر چه که هست کپی کنید.
http://www.codeproject.com/KB/silverlight/RIATasks/imgC.jpg
و آنرا در Source فایل Default.aspx از ابتدای تگ <DOCTYPE . . . تا انتهای صفحه به جای تمامی کدهای موجود الصاق کنید.
نیاز هست که تگ Div را که کنترل Silverlight در آن قرار دارد را به یک کنترل Panel تبدیل کنیم. کنترل Panel را می توان وقتی که کاربر در حالت logged in قرار ندارد به صورت hide در آورد.
برای انجام اینکار تغییرات زیر را انجام دهید
جایگزین کنید: <div id="silverlightControlHost">
با: <asp:panel id="silverlightControlHost" ="server">
جایگزین کنید: </div>
با: </asp:panel>
حالایک کنترل Drop-down به منظور ورود کاربر یا همان user log in درست در زیر تگ form اضافه کنید. در برنامه واقعی این کار باید در یک login form انجام شود.
کد های زیر را زیر تگ form الصاق کنید.

<asp:DropDownList ID="ddlUser" ="server" AutoPostBack="True"
onselectedindexchanged="ddlUser_SelectedIndexChanged">
<asp:ListItem Selected="True" Value="0">Logged Out</asp:ListItem>
<asp:ListItem Value="1">User One</asp:ListItem>
<asp:ListItem Value="2">User Two</asp:ListItem>
</asp:DropDownList>http://www.codeproject.com/KB/silverlight/RIATasks/img13.jpg
فایل Default.aspx.cs را باز کنید و تمامی کدهای زیر را در آن قرار دهید:


using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.Security;

namespace RIATasks.Web
{
public partial class Default : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
if (!Page.IsPostBack)
{
LogOut();
}
}

#region ddlUser_SelectedIndexChanged
protected void ddlUser_SelectedIndexChanged
(object sender, EventArgs e)
{
int intSelectedUser =
Convert.ToInt32(ddlUser.SelectedValue);
if (intSelectedUser > 0)
{
LogUserIntoSite
(Convert.ToInt32(ddlUser.SelectedValue));
}
else
{
LogOut();
}
}
#endregion

#region LogUserIn
private void LogUserIntoSite(int intUser)
{
// Log the user into the site
FormsAuthenticationTicket ticket =
new FormsAuthenticationTicket (1,
intUser.ToString(),
DateTime.Now,
DateTime.Now.AddDays(30),
false,
"Role One",
FormsAuthentication.FormsCookiePath);

// Encrypt the ticket.
string encTicket =
FormsAuthentication.Encrypt(ticket);

// Create the cookie.
Response.Cookies.Add
(new HttpCookie
(FormsAuthentication.FormsCookieName, encTicket));

// Show the Silverlight control
silverlightControlHost.Visible = true;
}
#endregion

#region LogOut
protected void LogOut()
{
FormsAuthentication.SignOut();

// Hide the Silverlight control
silverlightControlHost.Visible = false;
}
#endregion
}
}

http://www.codeproject.com/KB/silverlight/RIATasks/img1C.jpg
روی فایل Default.aspx کلیک راست کرده و آنرا به عنوان Start Page تعیین کنید.
برای اجرای برنامه می توانید از کلید F5 استفاده کنید. پروژه اجرا شده و در Web Browser باز می شود. شما می توانید محتویات drop down را به منظور log in شدن یک کاربر تغییر دهید.
Web browser را ببنید.
در قسمت سوم در خصوص نحوه ایجاد لایه Data صحبت خواهیم کرد.
اصل مقاله (http://www.codeproject.com/Articles/90071/RIATasks-A-Simple-Silverlight-CRUD-Example-using-V)

piroozman
چهارشنبه 15 خرداد 1392, 20:22 عصر
قسمت سوم:
ایجاد Data Layer
http://www.codeproject.com/KB/silverlight/RIATasks/img3.jpg
یک کلاس از نوع Linq to SQL به سایت RIATasks.Web تحت عنوان RIATasksDB.dbml اضافه کنید.
نکته: شما می توانید از Entity Framework به جای Linq to SQL ( یا هر نوع تکنولوژی دیگری که به Data دسترسی دارد) استفاده کنید. دلیل انتخاب Linq to SQL در این پروژه سهولت ایجاد تنظیمات آن می باشد.

http://www.codeproject.com/KB/silverlight/RIATasks/img4.gif
روی لینک Server Explorer کلیک کنید.
http://www.codeproject.com/KB/silverlight/RIATasks/img6.jpg
یک connection به دیتابیس RIATasks ایجاد کنید و جدول Tasks را با موس کشیده و در محیط Object Relational Designer رها کنید.
http://www.codeproject.com/KB/silverlight/RIATasks/img7.jpg
Data layer تکمیل شد. فایل را ذخیره کرده و آنرا ببندید.

ایجاد Web Service
http://www.codeproject.com/KB/silverlight/RIATasks/img12.jpg
یک فایل از نوع Web service به پروژه RIATasks تحت عنوان Webservice.asmx اضافه کنید.
فایل Webservice.asmx.cs را باز کنید و تمامی کدهای زیر را با کدهای موجود در آن جایگزین کنید:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Services;

namespace RIATasks.Web
{
[WebService(Namespace = "http://OpenLightGroup.org/")]
[WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
[System.ComponentModel.ToolboxItem(false)]
public class WebService : System.Web.Services.WebService
{
#region GetCurrentUserID
private int GetCurrentUserID()
{
int intUserID = -1;
if (HttpContext.Current.User.Identity.IsAuthenticated )
{
// Get the current user
intUserID =
Convert.ToInt32(HttpContext.Current.User.Identity. Name);
}
return intUserID;
}
#endregion

// Web Methods

#region GetTasks
[WebMethod]
public List<Task> GetTasks()
{
// Create a collection to hold the results
List<Task> colResult = new List<Task>();

RIATasksDBDataContext DB = new RIATasksDBDataContext();

var colTasks = from Tasks in DB.Tasks
where Tasks.UserID == GetCurrentUserID()
select Tasks;

// Loop thru the Tasks
foreach (var item in colTasks)
{
// Create a Task
Task tmpTask = new Task();

// Set only the TaskID and the Name
// We do this because Description could be
// a large amount of data that will slow down
// the application and we don"t need it now
tmpTask.TaskID = item.TaskID;
tmpTask.TaskName = item.TaskName;

// Add to the final results
colResult.Add(tmpTask);
}

return colResult;
}
#endregion

#region GetTask
[WebMethod]
public Task GetTask(int TaskID)
{
RIATasksDBDataContext DB = new RIATasksDBDataContext();

var result = (from Tasks in DB.Tasks
where Tasks.TaskID == TaskID
where Tasks.UserID == GetCurrentUserID()
select Tasks).FirstOrDefault();

return result;
}
#endregion

#region DeleteTask
[WebMethod]
public string DeleteTask(int TaskID)
{
string strError = "";
RIATasksDBDataContext DB = new RIATasksDBDataContext();

try
{
var result = (from Tasks in DB.Tasks
where Tasks.TaskID == TaskID
where Tasks.UserID == GetCurrentUserID()
select Tasks).FirstOrDefault();

if (result != null)
{
DB.Tasks.DeleteOnSubmit(result);
DB.SubmitChanges();
}
}
catch (Exception ex)
{
strError = ex.Message;
}

return strError;
}
#endregion

#region UpdateTask
[WebMethod]
public string UpdateTask(Task objTask)
{
string strError = "";
RIATasksDBDataContext DB = new RIATasksDBDataContext();

try
{
var result = (from Tasks in DB.Tasks
where Tasks.TaskID == objTask.TaskID
where Tasks.UserID == GetCurrentUserID()
select Tasks).FirstOrDefault();

if (result != null)
{
result.TaskDescription = objTask.TaskDescription;
result.TaskName = objTask.TaskName;

DB.SubmitChanges();
}
}
catch (Exception ex)
{
strError = ex.Message;
}

return strError;
}
#endregion

#region InsertTask
[WebMethod]
public Task InsertTask(Task objTask)
{
RIATasksDBDataContext DB = new RIATasksDBDataContext();

try
{
Task InsertTask = new Task();

InsertTask.TaskDescription = objTask.TaskDescription;
InsertTask.TaskName = objTask.TaskName;
InsertTask.UserID = GetCurrentUserID();

DB.Tasks.InsertOnSubmit(InsertTask);
DB.SubmitChanges();

// Set the TaskID
objTask.TaskID = InsertTask.TaskID;
}
catch (Exception ex)
{
// Log the error
objTask.TaskID = -1;
objTask.TaskDescription = ex.Message;
}

return objTask;
}
#endregion
}
}

توجه کنید که web service متد GetCurrentUserID() را که از Convert.ToInt32(HttpContext.Current.User.Identity. Name) استفاده می کند، برای به دست آوردن کاربر جاری فراخوانی می کند.
UserID کاربر جاری وقتی که به برنامه log in می کند مشخص می شود و یک authentication ‘token’ ایجاد می شود. Web browser کاربر ها این token را به ازای تمامی تقاضاها پاس می کنند. از جمله تقاضاهای وب سرویس که به واسطه برنامه Silverlight ایجاد می شوند.
http://www.codeproject.com/KB/silverlight/RIATasks/img20.jpg
برای بررسی صحت تنظیمات می توانید روی Webservice.asmx کلیک راست کرده و آن را با انتخاب گزینه View in Browser در مروگر خود ببینید.
http://www.codeproject.com/KB/silverlight/RIATasks/img19.gif
وب متدها به شما نمایش داده خواهد شد.
نکته: شما می توانید به جای asmx از WCF استفاده کنید. علت این انتخاب راحتی توسعه asmx می باشد.
در قسمت چهارم به سراغ پروژه Silverlight خواهیم رفت.
اصل مقاله (http://www.codeproject.com/Articles/90071/RIATasks-A-Simple-Silverlight-CRUD-Example-using-V)

piroozman
چهارشنبه 15 خرداد 1392, 20:46 عصر
قسمت چهارم:
پروژه Silverlight
http://www.codeproject.com/KB/silverlight/RIATasks/img21.jpg
حالا بریم سراغ پروژه RIATasks در قسمت Silverlight. ابتدا نیاز هست که یک reference از پروژه Silverlight به web service ای که درست کردیم ایجاد کنیم.
سپس باید یک Model برای فراخوانی وب سرویس ایجاد کنیم و همچنین یک کلاس پشتیبان ICommand ایجاد خواهیم کرد که به این اجازه رو می دهد که به آسانی رویدادها را در View Model بالا بیاوریم.

ایجاد Web Service Reference
http://www.codeproject.com/KB/silverlight/RIATasks/img36.jpg
در پروژه سیلورلایت روی گزینه References کلیک راست کنید و سپس Add Service Reference را انتخاب کنید.
http://www.codeproject.com/KB/silverlight/RIATasks/img38.jpg
روی دکمه Discover کلیک کنید
عبارت wsRIATasks را برای Namespace وارد کنید.
روی دکمه OK کلیک کنید.
ارتباط پروژه Silverlight با Website تکمیل شد. کدهایی که درمراحل بعدی ایجاد خواهیم کرد با استفاده از این Reference اقدام به فراخوانی web service ی که ایجاد کرده ایم خواهند کرد.

اضافه کردن References
یک Reference به Microsoft.VisualBasic و System.ServiceModelبه پروژه ایجاد کنید.
کلاس پشتیبان ICommand
http://www.codeproject.com/KB/silverlight/RIATasks/img24.jpg
یک پوشه جدید تحت عوان Classes به پروژه سیلورلایت اضافه کنید و روی آن کلیک راست کرده و گزینه New Item . . . را انتخاب کنید.
http://www.codeproject.com/KB/silverlight/RIATasks/img26.jpg
کلاسی تحت عوان DelegateCommand.cs ایجاد کنید و کد های زیر را در این کلاس جدید جایگزین کنید.

using System.Windows.Input;
using System;

namespace RIATasks
{
public class DelegateCommand : ICommand
{
Func<object, bool> canExecute;
Action<object> executeAction;
bool canExecuteCache;

public DelegateCommand(
Action<object> executeAction,
Func<object, bool> canExecute)
{
this.executeAction = executeAction;
this.canExecute = canExecute;
}

#region ICommand Members

public bool CanExecute(object parameter)
{
bool temp = canExecute(parameter);

if (canExecuteCache != temp)
{
canExecuteCache = temp;
if (CanExecuteChanged != null)
{
CanExecuteChanged(this, new EventArgs());
}
}

return canExecuteCache;
}

public event EventHandler CanExecuteChanged;

public void Execute(object parameter)
{
executeAction(parameter);
}

#endregion
}
}
این کلاس به آسانی به ما اجازه می دهد تا از ICommand ها را استفاده کنیم.
انشالله در قسمت بعدی می ریم به سراغ ساخت Model ها.
اصل مقاله (http://www.codeproject.com/Articles/90071/RIATasks-A-Simple-Silverlight-CRUD-Example-using-V)

piroozman
چهارشنبه 15 خرداد 1392, 21:01 عصر
قسمت پنجم:
Model
http://www.codeproject.com/KB/silverlight/RIATasks/img2A.jpg
یک پوشه جدید با نام Models ایجاد کنید و یک کلاس با نام TasksModel.cs در آن قراردهید و کد های زیر را در آن جایگزین کنید.

using Microsoft.VisualBasic;
using System.Linq;
using System;
using System.Collections.Generic;
using System.ServiceModel;
using RIATasks.wsRIATasks;

namespace RIATasks
{
public class TasksModel
{
#region GetTask
public static void GetTask(int TaskID,
EventHandler<GetTaskCompletedEventArgs> eh)
{
// Set up web service call
WebServiceSoapClient WS =
new WebServiceSoapClient();

// Set the EndpointAddress
WS.Endpoint.Address =
new EndpointAddress(GetBaseAddress());

WS.GetTaskCompleted += eh;
WS.GetTaskAsync(TaskID);
}
#endregion

#region GetTasks
public static void GetTasks
(EventHandler<GetTasksCompletedEventArgs> eh)
{
// Set up web service call
WebServiceSoapClient WS =
new WebServiceSoapClient();

// Set the EndpointAddress
WS.Endpoint.Address =
new EndpointAddress(GetBaseAddress());

WS.GetTasksCompleted += eh;
WS.GetTasksAsync();
}
#endregion

#region DeleteTask
public static void DeleteTask(int TaskID,
EventHandler<DeleteTaskCompletedEventArgs> eh)
{
// Set up web service call
WebServiceSoapClient WS =
new WebServiceSoapClient();

// Set the EndpointAddress
WS.Endpoint.Address =
new EndpointAddress(GetBaseAddress());

WS.DeleteTaskCompleted += eh;
WS.DeleteTaskAsync(TaskID);
}
#endregion

#region UpdateTask
public static void UpdateTask(Task objTask,
EventHandler<UpdateTaskCompletedEventArgs> eh)
{
// Set up web service call
WebServiceSoapClient WS = new WebServiceSoapClient();

// Set the EndpointAddress
WS.Endpoint.Address =
new EndpointAddress(GetBaseAddress());

WS.UpdateTaskCompleted += eh;
WS.UpdateTaskAsync(objTask);
}
#endregion

#region InsertTask
public static void InsertTask(Task objTask,
EventHandler<InsertTaskCompletedEventArgs> eh)
{
// Set up web service call
WebServiceSoapClient WS = new WebServiceSoapClient();

// Set the EndpointAddress
WS.Endpoint.Address = new EndpointAddress(GetBaseAddress());

WS.InsertTaskCompleted += eh;
WS.InsertTaskAsync(objTask);
}
#endregion

// Utility

#region GetBaseAddress
private static Uri GetBaseAddress()
{
// Get the web address of the .xap that launched this application
string strBaseWebAddress =
App.Current.Host.Source.AbsoluteUri;
// Find the position of the ClientBin directory
int PositionOfClientBin =
App.Current.Host.Source.AbsoluteUri.ToLower().Inde xOf(@"/clientbin");
// Strip off everything after the ClientBin directory
strBaseWebAddress =
Strings.Left(strBaseWebAddress, PositionOfClientBin);
// Create a URI
Uri UriWebService =
new Uri(String.Format(@"{0}/WebService.asmx",
strBaseWebAddress));
// Return the base address
return UriWebService;
}
#endregion
}
}

نکته: GetBaseAddress() متدی است که مشخص می کند که آیا کاربر xap. را راه اندازی کرده است ( Silverlight application در برگیرنده آن هست) و با استفاده از آن مشخص می شود که آیا WebService.asmx وجود دارد یا خیر؟ متدهای Web Service از این آدرس برای فراخوانی Web Service استفاده می کنند.
در حال حاضر ما متدها را در Model ایجاد کرده ایم. این متدها با متدهای موجود در Web Service که پیش از این ایجاده شده بودند در ارتباطند.
در قسمت ششم ساخت View Model را آموزش خواهیم داد.

piroozman
چهارشنبه 15 خرداد 1392, 21:31 عصر
قسمت ششم:
View Model
http://www.codeproject.com/KB/silverlight/RIATasks/img2C1.jpg
پوشه ای به نام ViewModels به پروژه ایجاد کرده و کلاسی تحت عنوان MainPageModel.cs به آن اضافه کنید. تمامی کدهای زیر را در آن جایگزین کنید:

using System;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Windows.Input;
using System.Windows;
using RIATasks.wsRIATasks;

namespace RIATasks
{
public class MainPageModel : INotifyPropertyChanged
{
public MainPageModel()
{
// Set the command property
GetTasksCommand = new DelegateCommand(GetTasks, CanGetTasks);
GetTaskCommand = new DelegateCommand(GetTask, CanGetTask);
DeleteTaskCommand = new DelegateCommand(DeleteTask, CanDeleteTask);
UpdateTaskCommand = new DelegateCommand(UpdateTask, CanUpdateTask);
AddNewTaskCommand = new DelegateCommand(AddNewTask, CanAddNewTask);

// The following line prevents Expression Blend
// from showing an error when in design mode
if (!DesignerProperties.IsInDesignTool)
{
// Get the Tasks for the current user
GetTasks();

// Set Visibility
HasCurrentTask = Visibility.Collapsed;
AddVisibility = Visibility.Visible;
UpdateVisibility = Visibility.Collapsed;
DeleteVisibility = Visibility.Collapsed;
}
}



// Utility

#region INotifyPropertyChanged
public event PropertyChangedEventHandler PropertyChanged;

private void NotifyPropertyChanged(String info)
{
if (PropertyChanged != null)
{
PropertyChanged(this, new PropertyChangedEventArgs(info));
}
}
#endregion
}
}
این کد INotifyPropertyChanged را که توسط Properties استفاده می شود ( در مراحل بعدی ایجاد خواهند شد) پیاده سازی می کند. این عمل موجب می شود که هر گونه تغییر و به روزرسانی در Properties در View قابل مشاهده باشد.
سازنده ()MainPageModel، بعضی از ICommand ها را که در مراحل بعدی به طور کامل تعریف خواهند شد، راه اندازی خواهد کرد. همچنین متد ()GetTasks را که موجب فراخوانی Model (که موجب فراخوانی web service خواهد شد) می شود را فراخوانی می کند و تمامی Task های کاربری را که به نرم افزار ورود پیدا کرده است را بازیابی می کند.
نکته: شما خطوط قرمز مواجی را زیر خطوط این کد مشاهده خواهید کرد زیرا مجموعه property ها و command ها هنوز به طور کامل تعریف نشده اند.
کدهای زیر را به به این کلاس اضافه کنید:

// Properties

#region CurrentTask
private Task _CurrentTask = new Task();
public Task CurrentTask
{
get { return _CurrentTask; }
private set
{
if (CurrentTask == value)
{
return;
}
_CurrentTask = value;
this.NotifyPropertyChanged("CurrentTask");
}
}
#endregion

#region AddVisibility
private Visibility _AddVisibility = Visibility.Visible;
public Visibility AddVisibility
{
get { return _AddVisibility; }
private set
{
if (AddVisibility == value)
{
return;
}
_AddVisibility = value;
this.NotifyPropertyChanged("AddVisibility");
}
}
#endregion

#region UpdateVisibility
private Visibility _UpdateVisibility = Visibility.Visible;
public Visibility UpdateVisibility
{
get { return _UpdateVisibility; }
private set
{
if (UpdateVisibility == value)
{
return;
}
_UpdateVisibility = value;
this.NotifyPropertyChanged("UpdateVisibility");
}
}
#endregion

#region DeleteVisibility
private Visibility _DeleteVisibility = Visibility.Visible;
public Visibility DeleteVisibility
{
get { return _DeleteVisibility; }
private set
{
if (DeleteVisibility == value)
{
return;
}
_DeleteVisibility = value;
this.NotifyPropertyChanged("DeleteVisibility");
}
}
#endregion

#region HasTasks
private Visibility _HasTasks = Visibility.Collapsed;
public Visibility HasTasks
{
get { return _HasTasks; }
private set
{
if (HasTasks == value)
{
return;
}
_HasTasks = value;
this.NotifyPropertyChanged("HasTasks");
}
}
#endregion

#region HasCurrentTask
private Visibility _HasCurrentTask = Visibility.Collapsed;
public Visibility HasCurrentTask
{
get { return _HasCurrentTask; }
private set
{
if (HasCurrentTask == value)
{
return;
}
_HasCurrentTask = value;
this.NotifyPropertyChanged("HasCurrentTask");
}
}
#endregion

#region Message
private string _Message;
public string Message
{
get { return _Message; }
private set
{
if (Message == value)
{
return;
}
_Message = value;
this.NotifyPropertyChanged("Message");
}
}
#endregion
مقدار کدها به نظر زیاد میاید اما آنها فقط Property هایی هستند که دادهایی را که قرار است در View به نمایش در آیند، در خود نگه می دارند. تغییر در هر کدام از Property ها موجب بالا آمدن NotifyPropertyChanged خواهد شد.
کدهای زیر را نیز به انتهای کلاس فوق اضافه کنید:

// Collections

#region colTasks
private ObservableCollection<Task> _colTasks
= new ObservableCollection<Task>();
public ObservableCollection<Task> colTasks
{
get { return _colTasks; }
private set
{
if (colTasks == value)
{
return;
}
_colTasks = value;
this.NotifyPropertyChanged("colTasks");
}
}
#endregion
کد فوق شبیه یک Property است اما در واقع یک Collection از Task ها است ( به جای یک تک مقدار یا Task).
هنوز ادامه دارد. لطفا کدهای زیر را نیز به انتهای همان کلاس اضافه کنید:

// Operations

#region GetTasks
private void GetTasks()
{
// Clear the current Tasks
colTasks.Clear();
// Call the Model to get the collection of Tasks
TasksModel.GetTasks((Param, EventArgs) =>
{
if (EventArgs.Error == null)
{
// loop thru each item
foreach (var Task in EventArgs.Result)
{
// Add to the colTasks collection
colTasks.Add(Task);
}

// Count the records returned
if (colTasks.Count == 0)
{
// If there are no records, indicate that
Message = "No Records Found";

// Set HasCurrentTask
HasCurrentTask = Visibility.Collapsed;

// We have no Tasks so set HasTasks
HasTasks = Visibility.Collapsed;
}
else
{
// We have Tasks so set HasTasks
HasTasks = Visibility.Visible;
}
}
});
}
#endregion

#region GetTask
private void GetTask(int intTaskID)
{
// Call the Model to get the Task
TasksModel.GetTask(intTaskID, (Param, EventArgs) =>
{
if (EventArgs.Error == null)
{
// Set the CurrentTask Property
CurrentTask = EventArgs.Result;

// Set Visibility
HasCurrentTask = Visibility.Visible;
AddVisibility = Visibility.Visible;
UpdateVisibility = Visibility.Visible;
DeleteVisibility = Visibility.Visible;
}
});
}
#endregion

#region DeleteTask
private void DeleteTask(Task objTask)
{
// Call the Model to delete the Task
TasksModel.DeleteTask(objTask.TaskID, (Param, EventArgs) =>
{
if (EventArgs.Error == null)
{
// Set the Error Property
Message = EventArgs.Result;

// Set current Task to null
CurrentTask = null;

// Update the Tasks list
GetTasks();

// Set Visibility
HasCurrentTask = Visibility.Collapsed;
AddVisibility = Visibility.Visible;
UpdateVisibility = Visibility.Collapsed;
DeleteVisibility = Visibility.Collapsed;
}
});
}
#endregion

#region UpdateTask
private void UpdateTask(Task objTask)
{
// Call the Model to UpdateTask the Task
TasksModel.UpdateTask(objTask, (Param, EventArgs) =>
{
if (EventArgs.Error == null)
{
// Set the Error Property
Message = EventArgs.Result;

// Update the Tasks list
GetTasks();

// Set Visibility
HasCurrentTask = Visibility.Visible;
AddVisibility = Visibility.Visible;
UpdateVisibility = Visibility.Visible;
DeleteVisibility = Visibility.Visible;
}
});
}
#endregion

#region InsertTask
private void InsertTask(Task objTask)
{
// Call the Model to Insert the Task
TasksModel.InsertTask(objTask, (Param, EventArgs) =>
{
if (EventArgs.Error == null)
{
// Set the CurrentTask Property
CurrentTask = EventArgs.Result;

// Update the Tasks list
GetTasks();

// Set Visibility
HasCurrentTask = Visibility.Visible;
AddVisibility = Visibility.Visible;
UpdateVisibility = Visibility.Visible;
DeleteVisibility = Visibility.Visible;
}
});
}
#endregion

#region SetToNewTask
private void SetToNewTask()
{
// Create a empty Task
// so form will be blank
Task objTask = new Task();

// Set TaskID = -1 so we know it"s
// a new Task
objTask.TaskID = -1;

// Set the CurrentTask Property
CurrentTask = objTask;

// Set Visibility
HasCurrentTask = Visibility.Visible;
AddVisibility = Visibility.Collapsed;
UpdateVisibility = Visibility.Visible;
DeleteVisibility = Visibility.Collapsed;
}
#endregion
یک سری عملیاتهایی وجود دارد که ViewModel آنها را اجرا خواهد کرد. در واقع توابع یا متدهایی هستند که کارهای واقعی را انجام می دهند. اکثر این متدها صرفاً متدهای Model را فراخوانی می کنند.
کدهای زیر را به انتهای کلاس اضافه کنید:
// Commands

#region GetTasksCommand
public ICommand GetTasksCommand { get; set; }
public void GetTasks(object param)
{
GetTasks();
}

private bool CanGetTasks(object param)
{
return true;
}
#endregion

#region GetTaskCommand
public ICommand GetTaskCommand { get; set; }
public void GetTask(object param)
{
// Get the Task that was passed as a parameter
Task objTask = (Task)param;

// Call GetTask to get and set
// the CurrentTask property
GetTask(objTask.TaskID);
}

private bool CanGetTask(object param)
{
// Only allow this ICommand to fire
// if a Task was passed as a parameter
return ((param as Task) != null);
}
#endregion

#region DeleteTaskCommand
public ICommand DeleteTaskCommand { get; set; }
public void DeleteTask(object param)
{
if (CurrentTask.TaskID == -1)
{
// This is a new Task
SetToNewTask();
}
else
{
// This is an Existing Task
DeleteTask(CurrentTask);
}
}

private bool CanDeleteTask(object param)
{
// Do not allow if there is no Current Task
return (CurrentTask != null);
}
#endregion

#region UpdateTaskCommand
public ICommand UpdateTaskCommand { get; set; }
public void UpdateTask(object param)
{
if (CurrentTask.TaskID == -1)
{
// This is a new Task
InsertTask(CurrentTask);
}
else
{
// This is an Update
UpdateTask(CurrentTask);
}
}

private bool CanUpdateTask(object param)
{
// Do not allow if there is no Current Task
return (CurrentTask != null);
}
#endregion

#region AddNewTaskCommand
public ICommand AddNewTaskCommand { get; set; }
public void AddNewTask(object param)
{
SetToNewTask();
}

private bool CanAddNewTask(object param)
{
return true;
}
#endregion
این کدها نیز ICommand ها بودند. کدهایی که توسط View فراخوانی خواهند شد.
http://www.codeproject.com/KB/silverlight/RIATasks/img5B.jpg
در Visual Studio از منوی Build گزینه Build RIATasks را انتخاب کنید. پروژه می بایست بدون هرگونه خطای Build شود.
در مرحله بعدی به ساخت View و ارتباط آن با Command ها و Property ها خواهیم پرداخت.

piroozman
چهارشنبه 15 خرداد 1392, 21:50 عصر
قسمت هفتم:
View
http://www.codeproject.com/KB/silverlight/RIATasks/img2E.jpg

http://www.codeproject.com/KB/silverlight/RIATasks/img6F.jpg
MainPage.xaml را در Expression Blend باز کنید.

http://www.codeproject.com/KB/silverlight/RIATasks/img71.jpg
پروژه در Expression Blend باز خواهد شد.
http://www.codeproject.com/KB/silverlight/RIATasks/img74.gif
روی LayoutRoot در پنجره Object and Timeline کلیک کرده و در پنجره Properties عبارت DataContext را در جعبه متن Search Properties تایپ کنید.
روی دکمه New کلیک کنید.
http://www.codeproject.com/KB/silverlight/RIATasks/img76.jpg
MainPageModel را از فضای نام {}RIATasks انتخاب کرده و Ok کنید (می توانید با تایپ MainPageModel در جعبه متن Search Objects شی مورد نظر را به راحتی بیابید).
http://www.codeproject.com/KB/silverlight/RIATasks/img79.jpg
به زبانه Data رفته و MainPageModel را بسط دهید (زیر بخش Data Context).
در این قسمت شما تمامی Property ها، Collection ها و ICommand های Public ی را که در MainPageModel وجود دارند را خواهید دید.
ایجاد Sample Data
http://www.codeproject.com/KB/silverlight/RIATasks/img7B.jpg
این کار موجب می شود که طراحی فرم راحتر شود و نیز شما امکان مشاهده داده های نمونه نیز وجود خواهد داشت.
در پنجره Data روی آیکون Create sample data کلیک کنید.
http://www.codeproject.com/KB/silverlight/RIATasks/img7D.gif
گزینه Create Sample Data from Class . . . را انتخاب کنید.
http://www.codeproject.com/KB/silverlight/RIATasks/img7F.jpg
در فضای نام{}RIATasks کلاس MainPageModel ار انتخاب کرده و روی OK کلیک کنید.
http://www.codeproject.com/KB/silverlight/RIATasks/img9F.jpg
MainPageModelSampleData را مشاهده می کنید.
ادامه مراحل ساخت View را در انشالله در قسمت بعدی.

piroozman
پنج شنبه 16 خرداد 1392, 00:09 صبح
قسمت هشتم:
ساخت View
http://www.codeproject.com/KB/silverlight/RIATasks/img82.jpg
روی colTasks در قسمت Sample Data کلیک کنید . . .
http://www.codeproject.com/KB/silverlight/RIATasks/img83.jpg
. . . و آن را روی صفحه رها کنید.
http://www.codeproject.com/KB/silverlight/RIATasks/img84.jpg
با این کار، یک ListBox با نمونه داده ها ایجاد خواهد شد.
نکته: در حال run-time اطلاعات واقعی اطلاعات نمونه نشان داده نخواهد شد.

http://www.codeproject.com/KB/silverlight/RIATasks/img9C.jpg
در Properties مربوط به ListBox مقادیر HorizontalAlignment به Left و VerticalAlignment را به Top تغییر دهید.
http://www.codeproject.com/KB/silverlight/RIATasks/img8B.jpg
روی ListBox کلیک راست کرده و گزینه
Edit additional Templates > Edit Generated Items > Edit Current
را انتخاب کنید.
http://www.codeproject.com/KB/silverlight/RIATasks/img99.jpg
در پنجره Object and Timeline روی سومین TextBlock کلیک کنید.
http://www.codeproject.com/KB/silverlight/RIATasks/img8E.jpg
در قسمت Properties مربوط به TextBlock در قسمت Text گزینه Advanced options :
http://www.codeproject.com/KB/silverlight/RIATasks/img8F.gif
گزینه Data Binding . . . ر انتخاب کنید.
نکته: نسخه Expression Blend مربوط به آموزش موجود در این مقاله 4 می باشد. در نسخه ی بالاتر ممکن است عبارات قدری متفاوت باشد. به طور مثال به جای عبارت Data Binding . . . شما عبارت Crate Data Binding . . . را خواهید دید.
http://www.codeproject.com/KB/silverlight/RIATasks/img9A.jpg
همانطور که می بینید این TextBlock به TaskName مقید(بایند) شده است. این تنها TextBlock ای است که می خواهیم در ListBox نمایش داده شود.
http://www.codeproject.com/KB/silverlight/RIATasks/img9B.jpg
در قسمت Objects and Timeline سایر TextBlock ها را حذف کنید.
http://www.codeproject.com/KB/silverlight/RIATasks/img96.jpg
بر روی آیکون Return scope کلیک کنید.
http://www.codeproject.com/KB/silverlight/RIATasks/img97.jpg
همانطور که می بینید ListBox شکل خود را یافته است.
http://www.codeproject.com/KB/silverlight/RIATasks/imgA3.jpg
حالا یک کنترل گرید انتخاب کنید.
http://www.codeproject.com/KB/silverlight/RIATasks/imgA4.jpg
Grid را درست بعد از ListBox و در مجاور آن قرار دهید.
http://www.codeproject.com/KB/silverlight/RIATasks/imgA5.jpg
با شناور نمودن موس در لبه های گرید و با فشردن دکمه چپ موس یک سلول ایجاد کنید.
http://www.codeproject.com/KB/silverlight/RIATasks/imgB6.jpg
از جعبه ابزار یک TexBox را گرفته . . .
http://www.codeproject.com/KB/silverlight/RIATasks/imgB7.jpg
. . . آنرا کشیده و روی Grid رها کنید.
http://www.codeproject.com/KB/silverlight/RIATasks/imgA9.jpg
از پنجره Data، گزینه TaskName را گرفته . . .
http://www.codeproject.com/KB/silverlight/RIATasks/imgB8.jpg
. . . و سپس آنرا روی TextBox رها کنید.
http://www.codeproject.com/KB/silverlight/RIATasks/imgA8.jpg
در Properties مربوط به TextBOx


Width و Height را به Auto تغییر دهید.
Horizontal و Vertical Alignment را مطابق شکل تنظیم کنید.
مقدار Margins را برابر صفر قرار دهید.

http://www.codeproject.com/KB/silverlight/RIATasks/imgBB.jpg
یک TextBox بر روی گرید قرار دهید.
http://www.codeproject.com/KB/silverlight/RIATasks/imgB0.jpg
در Properties مربوط به TextBOx


Width و Height را به Auto تغییر دهید.
Horizontal و Vertical Alignment را مطابق شکل تنظیم کنید.
مقدار Margins را برابر صفر قرار دهید.

http://www.codeproject.com/KB/silverlight/RIATasks/imgBD.jpg
از پنجره Data، گزینه TaskDescription را انتخاب کرده و روی این TextBox رها کنید.
http://www.codeproject.com/KB/silverlight/RIATasks/imgBF.jpg
دو TextBlock با متن Name و Description مطابق شکل در کنار TextBox های مربوطه قرار دهید.(برای این کار باید Text Properties. آنرا تغییر دهید)
http://www.codeproject.com/KB/silverlight/RIATasks/imgC2.jpg
در قسمت Tool Bar روی ابزار Button کلیک کنید.
http://www.codeproject.com/KB/silverlight/RIATasks/imgC3.jpg
در قسمت Tool Bar روی ابزار Button کلیک کنید.
http://www.codeproject.com/KB/silverlight/RIATasks/imgC7.jpg
مقدار Content آنرا به Add تغییر دهید.
http://www.codeproject.com/KB/silverlight/RIATasks/imgC6.jpg
دو کلید Update و Delete مطابق شکل به بالای ListBox اضافه کنید.
(ما در مراحل بعدی رویدادهای کلیک مربوط به این دکمه ها را تنظیم خواهیم کرد.)
تنظیمات مربوط به Visibility
الان تمامی کنترل های مورد نیاز روی صفحه قرار دارند، و هم اکنون می خواهیم Visibility را به کنترل های مختلف قلاب کنیم(hook up).
http://www.codeproject.com/KB/silverlight/RIATasks/imgDA.jpg
روی پنجره Object and Timeline روی کنترل Grid کلیک کنید.
http://www.codeproject.com/KB/silverlight/RIATasks/imgDB.jpg
در Properties مربوط به Grid، Advanced options مربوط به Visibility را انتخاب کنید.
http://www.codeproject.com/KB/silverlight/RIATasks/imgDC.gif
گزینه Data Binding . . .(در نسخه 5 Create Data Binding . . ) را انتخاب کنید.
http://www.codeproject.com/KB/silverlight/RIATasks/imgE2.jpg
گرید را به HasCurrentTask مقید نموده و روی OK کلیک کنید.
http://www.codeproject.com/KB/silverlight/RIATasks/imgE0.jpg
مابقی Visibility Properties را مطابق دیاگرام فوق به کنترل ها قلاب کنید.
http://www.codeproject.com/KB/silverlight/RIATasks/imgE7.jpg
نکته: اگر مقید سازی خصیصه Visibility موجب شود که برخی از کنترل ها در حال Desing (یا همان طراحی) دیده نشوند، می توانید فایل sample data را ویرایش کنید و . . .
http://www.codeproject.com/KB/silverlight/RIATasks/imgE6.jpg
. . . مقادیر آنها را به مقدار Visible تغییر دهید.
استفاده از رفتارها (Behaviors)
در این قسمت از رفتار InvokeCommandAction به منظور این که دکمه ها ICommand های تعریف شده در View Model را اجرا کنند، استفاده خواهیم کرد.
استفاده از Behaviors
در این قسمت از رفتار InvokeCommandAction به منظور این که دکمه ها ICommand های تعریف شده در View Model را اجرا کنند، استفاده خواهیم کرد.
اضافه کردن دکمه
http://www.codeproject.com/KB/silverlight/RIATasks/img9D.jpg
از طبقه مربوط به Behaviors کنترل InvokeCommadnAction را انتخاب کنید.(برای یافتن راحتر ان می توانید عبارت Invoke را در جعبه متن Search بنویسید).
http://www.codeproject.com/KB/silverlight/RIATasks/imgD4.jpg
و در پنجره Object and Timeline روی دکمه Add رها کنید.
http://www.codeproject.com/KB/silverlight/RIATasks/imgD5.jpg
در Properties مربوط به این Behavior:


گزینه Click را در قسمت EventName انتخاب کنید.
در قسمت Command Properties بر روی آیکون Data bind کلیک کنید.

http://www.codeproject.com/KB/silverlight/RIATasks/imgD6.jpg
به زبانه Data Context رفته، سپس گزینه AddNewTaskCommand را انتخاب کرده و روی دکمه OK کلیک کنید.
http://www.codeproject.com/KB/silverlight/RIATasks/imgF4.jpg
رفتار های InvokeCommandAction را به دکمه های Update، Delete و Add مطابق دیاگرام فوق اضافه کنید.
انتخاب یک Task از ListBox
http://www.codeproject.com/KB/silverlight/RIATasks/imgF6.jpg


یک InvokeCommandAction به ListBox اضافه کنید.
گزینه SelectionChanged را در قسمت EventName انتخاب کنید.
در قسمت Command بر روی آیکون Data bind کلیک کنید.

http://www.codeproject.com/KB/silverlight/RIATasks/imgF8.jpg
گزینه GetTaskCommand را انتخاب و روی OK کلیک کنید.
http://www.codeproject.com/KB/silverlight/RIATasks/imgF9.jpg
در قسمت CommandParameter بر روی Advanced Options کلیک کنید.
http://www.codeproject.com/KB/silverlight/RIATasks/imgFB.jpg
درقسمت ListBox گزینه SelectedItem را انتخاب و OK کنید.
افزودن Style
http://www.codeproject.com/KB/silverlight/RIATasks/image_thumb_9_.png
با کلیک بر روی این لینک (http://openlightgroup.net/Blog/tabid/58/EntryId/92/A-Total-Design-Change-Of-Your-Application-With-No-Code.aspx)در مورد ResourceDictionary و نحوه به کارگیری آنها بیشتر مطالعه کنید.
Build و اجرای پروژه
http://www.codeproject.com/KB/silverlight/RIATasks/img89.jpg
در پنجره Projecties، روی پروژه RIATasks.Web کلیک راست کرده و گزینه Startup Project را انتخاب کنید.
http://www.codeproject.com/KB/silverlight/RIATasks/img88.jpg
روی صفحه Default.aspx کلیک راست کرده و گزینه Startup را انتخاب کنید.
برای Build و اجرای پروژه از کلید F5 استفاده کنید.
http://www.codeproject.com/KB/silverlight/RIATasks/imgFD.jpg
پروژه کامل شد.

piroozman
پنج شنبه 16 خرداد 1392, 00:19 صبح
قسمت نهم(آخر):
وقتی می خواهید کد کمتری داشته باشید از View Model استفاده کنید.
مقید سازی ترکیب شده با INotifyPropertyChanged می تواند شما را از نوشتن کدهای زیاد نجات دهد. استفاده از View Model موجب می شود از ویژگیهای بسیار مفید موجود در Microsoft Expressions Blend بهره مند گردید. View Model همچنین یک الگوی ساده برای پیروی از آن است، بنابراین شما می توانید به سرعت و به راحتی Properties، Collections و ICommands را پیاده سازی کنید.
"کد سفارشی" (کد نویسی) واقعی شما در قسمت "Operations" هایی است که در قسمت View Model وجود دارد. شما می بینید که کد زیادی وجود نداشته و قسمت اعظم آن صرفا جهت فراخوانی Model و تنظیمات Properties در View Model نوشته شده است. در ضمن توجه داشته باشید که وقتی یک شی مانند یک Task به عنوان Task جاری انتخاب می شود، هیچ نیازی نیست که هریک از فیلد های موجود در شی Task تفکیک شود و پردازش هر یک از آنها به طور جداگانه انجام شود. ما کل شی Task را میان Model، View Model و View رد و بدل می کنیم.
این که ما می توانیم Property ها، مانند آنچه که در اشیاء سفارشی مانند Task و Visibility وجود داشت، را در View نمایش دهیم بسیار مفید می باشد و نگرانی نحوه پیاده سازی آنها را به طراحان می سپاریم. با فرض اینکه ما طراح هم باشیم، می توانیم از ویژگیهای Drag & Drop نرم افزار Expression Blend به سرعت و با دقت طراحی های مربوط به User Interface را انجام دهیم.
برنامه نویس می تواند صرفاً در نحوه ورود و خروج داده ها در View Model از طریق Model، و به تولید و اجرا درآودن لایه های تجاری تمرکز داشته باشد.
به عقیده من یک برنامه نویس متوجه خواهد شد که ما از ویژگی LESS CODE نهفته در View Model بهره مند شده ایم و اگر از این الگو استفاده نمی شد مطمئناًً با حجم بسیار بیشتر کد نویسی مواجه می شدیم.
حداقل، بسیاری از برنامه نویسانی که من با آنها کار کرده ام، تجربه بسیار لذت بخشی را در بهره مندی از این الگو داشته اند، چون می توانند بر روی منطق رویه ها تمرکز داشته باشند.
پروژه را نیز می توانید در انتهای همین مقاله دانلود کنید.
درباره نویسنده:
http://www.codeproject.com/script/Membership/ProfileImages/%7B9271A4D7-01AB-479B-A488-83FC2CB15E61%7D.jpg
Michael Washington is a Microsoft Silverlight MVP. He is a Silverlight developer and an ASP.NET, C#‎‎, and Visual Basic programmer.
He is a DotNetNuke Core member and has been involved with DotNetNuke for over 4 years. He is the Co-Author of Building Websites with DotNetNuke (4 and 5).
He is one of the founding members of The Open Light Group (http://openlightgroup.net).
He is the founder of http://LightSwitchHelpWebsite.com
He has a son, Zachary and resides in Los Angeles with his wife Valerie
.
موفق باشید . . .