سفارش تبلیغ
صبا ویژن

مرتب سازی
مرتب سازی را در انتهای این آموزش قرار داده ایم چون در واقع نیاز به کدنویسی بیشتری دارد. به هر حال در این مورد، View را تغییر چندانی نخواهیم داد (به جز تغییر در انقیاد DataGrid). آنچه نیاز به انجام آن می باشد ایجاد مجموعه ای است که ICollectionView مورد نظر ما را پیاده سازی کند.
به این دلیل نیاز به انجام این کار است که بتوانیم به رویدادهای هدف مجموعه دسترسی داشته باشیم و وقتی کاربری DataGrid را مرتب می کند آنها را کشف کنیم. در حال حاضر، DataGrid مرتب می شود. اما فقط صفحه جاری مرتب می شود. به جای این که اجازه دهیم DataGrid به طور خودکار مرتب سازی را انجام دهد، ما Web Service را فراخوانی کرده و رکوردهای آنرا مرتب می کنیم و سپس صفحه جاری را با داده هایی که عمل مرتب سازی روی آنها انجام شده است نمایش می دهیم.
در اینجا یه تجربه مرتب سازی صحیح را ارائه خواهیم کرد. برای مثال، اگر شما در صفحه دوم باشید و رکورد ها را بر اساس شماره ID مرتب کنید، صفحه دوم از کل مجموعه مرتب شده را مشاهده خواهید کرد.
متد GetRIAComments Web Service تغییر دهید طوری که پارامترهای مرتب سازی را بتوان به آن پاس کرد تا بتوان از آنها برای انجام کوئری به کار برد:


#region GetRIAComments
[WebMethod]
public List<RIAComment> GetRIAComments(int intPage,
                   string SortProperty, string SortDirection)
{
    // Create a collection to hold the results
    List<RIAComment> colResult = new List<RIAComment>();

    RIATasksDBDataContext DB = new RIATasksDBDataContext();

    var colRIAComments = from RIAComments in DB.RIAComments
                         select RIAComments;

    if (SortDirection == "Descending")
    {
        switch (SortProperty)
        {
            case "CommentID":
                colRIAComments = colRIAComments.OrderByDescending(x => x.CommentID);
                break;
            case "Comment":
                colRIAComments = colRIAComments.OrderByDescending(x => x.Comment);
                break;
            case "CommentUpdateDate":
                colRIAComments =
                  colRIAComments.OrderByDescending(x => x.CommentUpdateDate);
                break;
            default:
                colRIAComments = colRIAComments.OrderByDescending(x => x.CommentID);
                break;
        }
    }
    else
    {
        switch (SortProperty)
        {
            case "CommentID":
                colRIAComments = colRIAComments.OrderBy(x => x.CommentID);
                break;
            case "Comment":
                colRIAComments = colRIAComments.OrderBy(x => x.Comment);
                break;
            case "CommentUpdateDate":
                colRIAComments = colRIAComments.OrderBy(x => x.CommentUpdateDate);
                break;
            default:
                colRIAComments = colRIAComments.OrderBy(x => x.CommentID);
                break;
        }
    }

    // Compute the CurrentPage
    int CurrentPage = ((intPage * 5) - 5);
    // Implement paging
    colRIAComments = colRIAComments.Skip(CurrentPage).Take(5);

    // Loop thru the Tasks
    foreach (var item in colRIAComments)
    {
        // Create a Task
        RIAComment OutputRIAComment = new RIAComment();

        // Get only the first 25 charaters of the comment
        OutputRIAComment.CommentID = item.CommentID;
        OutputRIAComment.Comment = Strings.Left(item.Comment, 25) + " ...";
        OutputRIAComment.CommentUpdateDate = item.CommentUpdateDate;

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

    return colResult;
}
#endregion


 
روی wsRIARIAComments web reference کلیک راست کرده و Update Service Reference کلیک کنید.
متد GetRIAComments موجود در Model را مطابق کدهای زیر تغییر دهید:


#region GetRIAComments
public static void GetRIAComments(int intPage, string SortProperty,
       string SortDirection, EventHandler<GetRIACommentsCompletedEventArgs> eh)
{
    // Set up web service call
    WebServiceSoapClient WS = new WebServiceSoapClient();

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

    WS.GetRIACommentsCompleted += eh;
    WS.GetRIACommentsAsync(intPage, SortProperty, SortDirection);
}
#endregion


این کد اجازه می دهد پارامترهای مرتب سازی به متد GetRIAComments موجود در وب سرویس پاس شود.
کدهای زیر را به خواص موجود در View Model اضافه کنید:


#region ViewSource
private CollectionViewSource _ViewSource = new CollectionViewSource();
public CollectionViewSource ViewSource
{
    get { return _ViewSource; }
    private set
    {
        _ViewSource = value;
        this.NotifyPropertyChanged("ViewSource");
    }
}
#endregion


این کد یک CollectionViewSource فراهم می کند که می توانیم دیتاگرید را به آن مقید کنیم. وقتی این کار انجام شد، DataGrid از View Source داخلی دیگر استفاده ای نخواهد کرد. سپس قادر خواهیم بود رویداد های مربوط به مرتب سازی را گیر بیاندازیم که در غیر این صورت انکان دسترسی به آنها غیر ممکن خواهد بود.
Property های زیر را به View Model اضافه کنید:


#region SortProperty
private string _SortProperty;
public string SortProperty
{
    get { return _SortProperty; }
    private set
    {
        if (SortProperty == value)
        {
            return;
        }
        _SortProperty = value;
        this.NotifyPropertyChanged("SortProperty");
    }
}
#endregion

#region SortDirection
private string _SortDirection;
public string SortDirection
{
    get { return _SortDirection; }
    private set
    {
        if (SortDirection == value)
        {
            return;
        }
        _SortDirection = value;
        this.NotifyPropertyChanged("SortDirection");
    }
}
#endregion


خواص فوق فیلد جاری ای را که مرتب سازی براساس آن انجام شده و نیز جهتی (Direction) ای را که مرتب سازی بر اساس آن انجام شده را ذخیره خواهند کرد.
کدهای زیر با سازنده View Model اضافه کنید:


// Connect the ViewSource to the Comments collection
// The DataGrid will be bound to the ViewSource so that it
// can implement sorting that we can wire-up an event handler to
ViewSource.Source = colRIAComments;

// Wire-up an event handler to the SortDescriptions collection on the ViewSource
INotifyCollectionChanged sortchangeNotifier =
          ViewSource.View.SortDescriptions as INotifyCollectionChanged;

// Call View_CollectionChanged when the SortDescriptions collection is changed
sortchangeNotifier.CollectionChanged +=
          new NotifyCollectionChangedEventHandler(View_CollectionChanged);


این کد، colRIAComments را به CollectionViewSource (ViewSource) تخصیص می دهد.
سپس به یک کنترل کننده تغییرات در SortDescriptions مربوط به CollectionViewSource متصل می شود. CollectionViewSource وقتی نوع مرتب سازی DataGrid که به collection مقید است، تغییر می یابد (هنگام کلیک کاربر بروی سرستونهای DataGrid) به طور خودکار مجموعه SortDescriptions را تغییر می دهد.
کدهای زیر را برای پاسخ به رویداد به View Model اضافه کنید:


#region View_CollectionChanged
void View_CollectionChanged(object sender, NotifyCollectionChangedEventArgs e)
{
    // Clear the underlying collection to prevent the ViewSource
    // from sorting the collection currently displayed in the ViewSource
    // and then sorting it again after the web service call
    colRIAComments.Clear();

    // When the sort is in Add mode, it is the second (the last step)
    // of defining a new Sort
    if (e.Action == NotifyCollectionChangedAction.Add)
    {
        // re-query the datasource
        GetRIAComments();
    }
}
#endregion


متد فوق چندین بار فراخوانی خواهدشد (یک برای هر Action ای که در مجموعه SortDescriptions قراردارد) و این که وقتی بخواهیم عمل پرس و جو وب سرویس را مجدداً (re-query web service) انجام دهیم و رکورد ها را واکشی کنیم، مرتب سازی جاری را پاس خواهیم کرد.
متد زیر را به کلاس بیافزایید:


#region SetSortProperties
private void SetSortProperties()
{
    // Set the Sort PropertyName and Direction
    // If there is anything in the SortDescriptions collection
    // Items are placed here when the Control attached to this ViewSource
    // is sorted (for example, by clicking on the Header in the DataGrid)
    if (ViewSource.View != null)
    {
        if (ViewSource.View.SortDescriptions.Count > 0)
        {
            SortProperty = ViewSource.View.SortDescriptions[0].PropertyName;
            SortDirection = ViewSource.View.SortDescriptions[0].Direction.ToString();
        }
    }
}
#endregion


این کد به مجموعه SortDescriptions نگاه می کند و property (نام فیلد) ی که مرتب سازی و جهت دهی باید بر اساس آنها انجام شود را بیرون می کشد. این مقادیر در SortProperty و خواص SortDirection (که پیش از این ایجاد شده بودند) قرار دارد. این مقادیر به Web Service پاسخ خواهند شد.
متد فوق به وسیله متد زیر که تغییر یافته متد GetRIAComments است فراخوانی خواهد شد:


#region GetRIAComments
private void GetRIAComments()
{
    // Set Sort Properties if there are any
    SetSortProperties();

    // Call the Model to get the collection of RIAComments
    RIACommentsModel.GetRIAComments(CurrentPage, SortProperty,
                     SortDirection, (Sender, EventArgs) =>
    {
        if (EventArgs.Error == null)
        {
            // Clear the current RIAComments
            colRIAComments.Clear();

            // loop thru each item
            foreach (var RIAComment in EventArgs.Result)
            {
                // Add to the colRIAComments collection
                colRIAComments.Add(RIAComment);
            }
        }
    });
}
#endregion


این متد Web Service را فراخوانی کرده و صفحه رکوردها را واکشی خواهد کرد.
 
در آخرین مرحله پروژه را Build کنید. سپس روی DataGrid کلیک کنید و در خواص آن در کنار ItemsSource گزینه Advanced options را انتخاب کنید.
 
Data Binding... را انتخاب کنید.
 
و آنرا به ViewSource>View مقید کنید.
 
حالا، اگر به صفحه آخر رفته و آنرا مرتب کنید، کل مجموعه مرتب خواهد شد، (و نه فقط رکوردهای قابل مشاهده در آخرین صفحه).


Style

به سادگی می توانید کل برنامه را قالب بندی (Theme) کنید. ابتدا Silverlight Toolkit را نصب کنید.
 
Theme را بیابید و تم مورد نظر را انتخاب کنید و . . .
 
. . . و آنرا روی [UserControl] رها کنید.
 
برنامه قالب بندی می شود.
ViewModel کد کمتر، واقعاً!
خوشحالم که تا انتهای این مقاله با ما بودید و دیدید که کدنویسی View Model همیشه سخت نیست. با یک نگاه به چگونگی تولید آن متوجه خواهید شد که این شیوه ایجاد آن چندان پیچیده نیست. Expression Blend برای کار با “View Model Styel”  طراحی شده است، بنابراین با استفاده از Expression Blend درهنگام به کارگیری این الگوی ساده ، اوقات راحتری را خواهید داشت.
در حالی که به نظر می رسد پیاده سازی یک DataGrid با استفاده از code-behind ساده تر است، اکثر اوقات متوجه خواهید شد که مقدار کد زیادی را برای جستجو، تغییر مقادیر و خواص در DataGrid باید تولید کنید.
کنترل هایی مانند DataGrid برای انقیاد به مجموعه ها طراحی شده اند. View Model برای پیاده سازی عملیات انقیاد پیاده سازی می شود. View Model انقیادی است که موجب صرفه جویی در کدهای شما خواهد شد. هنگامی که یک انقیاد ایجاد می شود، کاهش میزان کدنویسی به خودی خود انجام می شود. مجبور نیستید که صراحتاً برای هر قسمت از عملکردها کد نویسی کنید.
علاوه براین، متوجه شدید که بسیاری از قابلیت های برنامه نویسی به بهترین نحو در داخل منابع داده پیاده سازی شده است و نه در خود DataGrid. همچنین توجه داشته باشید که این مثال از Web Service های استاندارد استفاده کرده است و شما می توانید به راحتی از WCF یا WCF RIA نیز استفاده کنید. تغییر در نوع Web Service تاثیری بر روی View و View Model نداشته و به همین شکل خواهند بود.


اولین دیدگاه را شما بگذارید Silverlight ، MVVM ، Expression Blend ،

 حذف ردیف...   

مشخصات مدیر وبلاگ

محمد محمدی پیروز [33]

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

لوگوی دوستان



ویرایش

طراحی پوسته توسط تیم پارسی بلاگ