zoukankan      html  css  js  c++  java
  • 稳扎稳打Silverlight(61) 4.0通信之WCF RIA Services: 自定义服务端排序和分页

    [索引页]
    [源码下载]


    稳扎稳打Silverlight(61) - 4.0通信之WCF RIA Services: 自定义服务端排序和分页



    作者:webabcd


    介绍
    Silverlight 4.0 之 WCF RIA Services:实现自定义的服务端排序和分页


    在线DEMO
    http://www.cnblogs.com/webabcd/archive/2010/08/09/1795417.html


    示例
    演示如何在 WCF RIA Services 框架中实现自定义的服务端排序和分页
    1、服务端
    MyDomainService.cs

    代码
    /*
     * 一个 Domain Service 服务
     
    */

    namespace Silverlight40.Web.Service
    {
        
    using System;
        
    using System.Collections.Generic;
        
    using System.ComponentModel;
        
    using System.ComponentModel.DataAnnotations;
        
    using System.Data;
        
    using System.Linq;
        
    using System.ServiceModel.DomainServices.EntityFramework;
        
    using System.ServiceModel.DomainServices.Hosting;
        
    using System.ServiceModel.DomainServices.Server;
        
    using Silverlight40.Web.Model;

        
    /*
         * 用 LinqToEntities 实现 Domain Service 则继承 LinqToSqlDomainService<NorthwindEntities>;用 LinqToSql 实现 Domain Service 则继承 LinqToSqlDomainService<NorthwindEntities>
         * Domain Service 内所有对客户端可见的方法都应该是 public 的,Domain Service 内的方法不支持重载
         * 对客户端可见的方法要满足命名约定,或为其指定对应的 Attribute。当前支持 6 种数据操作:Query, Update, Insert, Delete, Invoke, Named Update, 详见文档
         * 
         * [EnableClientAccess()] - 该类对客户端可见
         * [EnableClientAccess(RequiresSecureEndpoint = true)] - 使用 HTTPS 协议
         * [Ignore] - 指定的方法不作为服务而公开
         * [Query(IsComposable=true)] - 支持客户端的 linq 查询,而且此查询会被在服务端执行
         * 
         * 在多个 Domain Services 间共享实体:通过 [ExternalReference], [Association()], Context.AddReference() 实现,详见文档
         
    */

        
    // 服务端的类名为:MyDomainService,则其生成的客户端上下文的类名为:MyDomainContext
        [EnableClientAccess()]
        
    public class MyDomainService : LinqToEntitiesDomainService<NorthwindEntities>
        {
            [Query(IsDefault 
    = true)]
            
    public IQueryable<Category> GetCategories()
            {
                
    return this.ObjectContext.Categories;
            }

            
    public void InsertCategory(Category category)
            {
                
    if ((category.EntityState != EntityState.Detached))
                {
                    
    this.ObjectContext.ObjectStateManager.ChangeObjectState(category, EntityState.Added);
                }
                
    else
                {
                    
    this.ObjectContext.Categories.AddObject(category);
                }
            }

            
    public void UpdateCategory(Category currentCategory)
            {
                
    this.ObjectContext.Categories.AttachAsModified(currentCategory, this.ChangeSet.GetOriginal(currentCategory));
            }

            
    public void DeleteCategory(Category category)
            {
                
    if ((category.EntityState == EntityState.Detached))
                {
                    
    this.ObjectContext.Categories.Attach(category);
                }
                
    this.ObjectContext.Categories.DeleteObject(category);
            }



            [Query(IsDefault 
    = true)]
            
    public IQueryable<Product> GetProducts()
            {
                
    return this.ObjectContext.Products;
            }

            
    public IQueryable<Product> GetProductsBySort(string sort)
            {
                
    return ObjectContext.Products.OrderBy(sort);
            }

            
    public void InsertProduct(Product product)
            {
                
    if ((product.EntityState != EntityState.Detached))
                {
                    
    this.ObjectContext.ObjectStateManager.ChangeObjectState(product, EntityState.Added);
                }
                
    else
                {
                    
    this.ObjectContext.Products.AddObject(product);
                }
            }

            
    public void UpdateProduct(Product currentProduct)
            {
                
    this.ObjectContext.Products.AttachAsModified(currentProduct, this.ChangeSet.GetOriginal(currentProduct));
            }

            
    public void DeleteProduct(Product product)
            {
                
    if ((product.EntityState == EntityState.Detached))
                {
                    
    this.ObjectContext.Products.Attach(product);
                }
                
    this.ObjectContext.Products.DeleteObject(product);
            }

            
    public IQueryable<Product> GetProductsByCategoryId(int categoryId)
            {
                
    return this.ObjectContext.Products.Where(p => p.CategoryID == categoryId);
            }



            
    // 通过验证的并且角色属于“管理员”的用户才有权限调用此方法
            [Invoke]
            [RequiresAuthentication()]
            [RequiresRole(
    "管理员")]
            
    public string GetAuthenticationStatus()
            {
                
    return "看到了这条信息,就证明你有权限";
            }
        }
    }



    MyDomainService.metadata.cs

    代码
    /*
     * [MetadataTypeAttribute()] - 指定类的元数据对象
     * [Include] - 生成的客户端上下文包含此字段
     * [Exclude] - 生成的客户端上下文不包含此字段
     * [Composition] - 指定字段为关联数据,即父实体增删改查时,此关联数据也会做相应的变化。指定此 Attribute 后,需显式指定其为 [Include]
     *     注:如果使用 DomainDataSource 则不能将字段设置为 [Composition]
     * [Editable(true)], [Editable(false)] - 指定字段是否可编辑
     * 
     * 支持 Data Annotation 方式的数据验证:DataTypeAttribute(具有很多常用的数据类型的验证), RangeAttribute, RegularExpressionAttribute, RequiredAttribute, StringLengthAttribute 等
     * 注:如果需要将自定义的验证既作用于服务端又作用于客户端,则需要把自定义的验证逻辑代码设置为 shared 模式
     
    */

    namespace Silverlight40.Web.Model
    {
        
    using System;
        
    using System.Collections.Generic;
        
    using System.ComponentModel;
        
    using System.ComponentModel.DataAnnotations;
        
    using System.Data.Objects.DataClasses;
        
    using System.Linq;
        
    using System.ServiceModel.DomainServices.Hosting;
        
    using System.ServiceModel.DomainServices.Server;

        
    using Silverlight40.Web.Service.Validation;

        [MetadataTypeAttribute(
    typeof(Category.CategoryMetadata))]
        [CustomValidation(
    typeof(CategoryValidator), "ValidateCategory")] // 演示通过自定义的实体验证器来实现验证
        public partial class Category
        {
            
    internal sealed class CategoryMetadata
            {
                
    private CategoryMetadata()
                {
                }

                [Key()]
                
    public int CategoryID { getset; }

                [Display(Name 
    = "类别名称")] // 显示用
                [Numeric(ErrorMessage = "字段“{0}”必须是数字")] // 演示通过继承 RegularExpressionAttribute 实现字段的自定义验证
                [StartsWith(ErrorMessage = "{0}")] // 演示通过继承 ValidationAttribute 实现字段的自定义验证
                [CustomValidation(typeof(EndsWidthValidator), "ValidateCategoryName")]  // 演示通过自定义的字段验证器来实现验证
                public string CategoryName { getset; }

                
    public string Description { getset; }

                [Exclude]
                
    public byte[] Picture { getset; }

                [Include]
                [Composition]
                
    public EntityCollection<Product> Products { getset; }
            }
        }

        [MetadataTypeAttribute(
    typeof(Product.ProductMetadata))]
        
    public partial class Product
        {
            
    internal sealed class ProductMetadata
            {
                
    private ProductMetadata()
                {
                }

                
    public Category Category { getset; }

                
    public Nullable<int> CategoryID { getset; }

                
    public bool Discontinued { getset; }

                
    public EntityCollection<Order_Detail> Order_Details { getset; }

                [Display(Order 
    = 0, Name = "产品ID")]
                
    public int ProductID { getset; }

                [Display(Order 
    = 1, Name = "产品名称")]
                
    public string ProductName { getset; }

                
    public string QuantityPerUnit { getset; }

                
    public Nullable<short> ReorderLevel { getset; }

                
    public Supplier Supplier { getset; }

                
    public Nullable<int> SupplierID { getset; }

                
    public Nullable<decimal> UnitPrice { getset; }

                
    public Nullable<short> UnitsInStock { getset; }

                
    public Nullable<short> UnitsOnOrder { getset; }
            }
        }
    }



    2、客户端
    ReloadEventArgs.cs

    代码
    using System;
    using System.Net;
    using System.Windows;
    using System.Windows.Controls;
    using System.Windows.Documents;
    using System.Windows.Ink;
    using System.Windows.Input;
    using System.Windows.Media;
    using System.Windows.Media.Animation;
    using System.Windows.Shapes;

    using System.ComponentModel;

    namespace Silverlight40.WCFRIAServices.CustomSortingPaging
    {
        
    // 刷新事件的事件参数
        public class ReloadEventArgs : EventArgs
        {
            
    public SortDescriptionCollection SortDescriptions { getset; }
        }
    }


    SortableCollectionView.cs

    代码
    using System;
    using System.Net;
    using System.Windows;
    using System.Windows.Controls;
    using System.Windows.Documents;
    using System.Windows.Ink;
    using System.Windows.Input;
    using System.Windows.Media;
    using System.Windows.Media.Animation;
    using System.Windows.Shapes;

    using System.Collections.ObjectModel;
    using System.ComponentModel;
    using System.Collections.Generic;
    using System.Linq;

    namespace Silverlight40.WCFRIAServices.CustomSortingPaging
    {
        
    // 为了实现排序功能,所以需要实现 ICollectionView 接口(仅实现其中的排序功能部分)
        
    // 为了集合具有改变通知的功能,所以需要继承自 ObservableCollection<T>
        public class SortableCollectionView<T> : ObservableCollection<T>, ICollectionView
        {
            
    public SortableCollectionView()
            {
                _currentItem 
    = null;
                _currentPosition 
    = -1;
            }

            
    protected override void ClearItems()
            {
                
    base.ClearItems();

                
    // 触发 CurrentChanging 事件
                OnCurrentChanging();
            }



            
    public bool CanFilter
            {
                
    get { return false; }
            }

            
    public bool CanGroup
            {
                
    get { return false; }
            }

            
    // 允许通过 SortDescriptions 属性进行排序
            public bool CanSort
            {
                
    get { return true; }
            }

            
    public System.Globalization.CultureInfo Culture { getset; }

            
    // 当前项
            private object _currentItem;
            
    public object CurrentItem
            {
                
    get { return _currentItem; }
            }

            
    // 当前项的索引
            private int _currentPosition;
            
    public int CurrentPosition
            {
                
    get { return _currentPosition; }
            }

            
    public Predicate<object> Filter { getset; }

            
    public ObservableCollection<GroupDescription> GroupDescriptions
            {
                
    get { return null; }
            }

            
    public ReadOnlyObservableCollection<object> Groups
            {
                
    get { return null; }
            }

            
    // 当前项是否超出了集合的末尾
            public bool IsCurrentAfterLast
            {
                
    get
                {
                    
    if (!IsEmpty)
                        
    return CurrentPosition >= base.Count;

                    
    return true;
                }
            }

            
    // 当前项是否超出了集合的开头
            public bool IsCurrentBeforeFirst
            {
                
    get
                {
                    
    if (!IsEmpty)
                        
    return CurrentPosition < 0;

                    
    return true;
                }
            }

            
    // 集合是否为空
            public bool IsEmpty
            {
                
    get { return base.Count == 0; }
            }

            
    // System.ComponentModel.SortDescription 类型对象的集合,其用于描述集合中的数据的排序方式
            private SortDescriptionCollection _sortDescriptions;
            
    public SortDescriptionCollection SortDescriptions
            {
                
    get
                {
                    
    if (_sortDescriptions == null)
                        _sortDescriptions 
    = new SortDescriptionCollection();

                    
    return _sortDescriptions;
                }
            }

            
    public System.Collections.IEnumerable SourceCollection
            {
                
    get { return this; }
            }

            
    // 当前项更改后所触发的事件
            public event EventHandler CurrentChanged;

            
    // 当前项准备更改之前所触发的事件
            public event CurrentChangingEventHandler CurrentChanging;

            
    // 指定的项是否属于此集合
            public bool Contains(object item)
            {
                
    return Contains((T)item);
            }

            
    // 延迟刷新
            public IDisposable DeferRefresh()
            {
                
    return new DeferRefreshHelper(() => Refresh());
            }
            
    private class DeferRefreshHelper : IDisposable
            {
                
    private Action _callback;

                
    public DeferRefreshHelper(Action callback)
                {
                    _callback 
    = callback;
                }

                
    public void Dispose()
                {
                    _callback();
                }
            }

            
    // 将指定项设置为当前项
            public bool MoveCurrentTo(object item)
            {
                
    if (object.Equals(CurrentItem, item) && (item != null || IsCurrentInView))
                    
    return IsCurrentInView;

                
    int index = base.IndexOf((T)item);

                
    return MoveCurrentToPosition(index);
            }

            
    // 将第一项设置为当前项
            public bool MoveCurrentToFirst()
            {
                
    return MoveCurrentToPosition(0);
            }

            
    // 将最后一项设置为当前项
            public bool MoveCurrentToLast()
            {
                
    return MoveCurrentToPosition(base.Count - 1);
            }

            
    // 将当前项的下一项设置为当前项
            public bool MoveCurrentToNext()
            {
                
    return CurrentPosition < base.Count && MoveCurrentToPosition(CurrentPosition + 1);
            }

            
    // 将指定位置的项设置为当前项
            public bool MoveCurrentToPosition(int position)
            {
                
    if (position < -1 || position > base.Count)
                    
    throw new Exception("参数“position”不在范围内");

                
    if (position != CurrentPosition)
                {
                    
    bool isCurrentAfterLast = IsCurrentAfterLast;
                    
    bool isCurrentBeforeFirst = IsCurrentBeforeFirst;

                    OnCurrentChanging();
                    ChangeCurrentToPosition(position);
                    OnCurrentChanged();

                    
    if (IsCurrentAfterLast != isCurrentAfterLast)
                        OnPropertyChanged(
    "IsCurrentAfterLast");
                    
    if (IsCurrentBeforeFirst != isCurrentBeforeFirst)
                        OnPropertyChanged(
    "IsCurrentBeforeFirst");

                    OnPropertyChanged(
    "CurrentPosition");
                    OnPropertyChanged(
    "CurrentItem");
                }

                
    return IsCurrentInView;
            }

            
    // 将当前项的上一项设置为当前项
            public bool MoveCurrentToPrevious()
            {
                
    return CurrentPosition >= 0 && MoveCurrentToPosition(CurrentPosition - 1);
            }

            
    public event EventHandler<ReloadEventArgs> Reload;
            
    // 刷新集合
            public void Refresh()
            {
                
    if (Reload != null)
                    Reload(
    thisnew ReloadEventArgs() { SortDescriptions = SortDescriptions });
            }

            
    protected virtual void OnCurrentChanged()
            {
                
    if (CurrentChanged != null)
                    CurrentChanged(
    this, EventArgs.Empty);
            }

            
    protected virtual void OnCurrentChanging(CurrentChangingEventArgs args)
            {
                
    if (args == null)
                    
    throw new Exception("参数“args”不能为 null");

                
    if (CurrentChanging != null)
                    CurrentChanging(
    this, args);
            }

            
    protected void OnCurrentChanging()
            {
                _currentPosition 
    = -1;

                OnCurrentChanging(
    new CurrentChangingEventArgs(false));
            }

            
    protected virtual void OnPropertyChanged(string propertyName)
            {
                
    base.OnPropertyChanged(new PropertyChangedEventArgs(propertyName));
            }



            
    // 获取集合内指定位置的对象
            private object GetItemAt(int index)
            {
                
    if (index >= 0 && index < base.Count)
                    
    return this[index];

                
    return null;
            }

            
    // 当前项是否在集合的范围之内
            private bool IsCurrentInView
            {
                
    get { return CurrentPosition >= 0 && CurrentPosition < base.Count; }
            }

            
    // 将指定位置的项设置为当前项
            private void ChangeCurrentToPosition(int position)
            {
                
    if (position < 0)
                {
                    _currentItem 
    = null;
                    _currentPosition 
    = -1;
                }
                
    else if (position >= base.Count)
                {
                    _currentItem 
    = null;
                    _currentPosition 
    = base.Count;
                }
                
    else
                {
                    _currentItem 
    = this[position];
                    _currentPosition 
    = position;
                }
            }
        }
    }


    PageableSortableCollectionView.cs

    代码
    using System;
    using System.Net;
    using System.Windows;
    using System.Windows.Controls;
    using System.Windows.Documents;
    using System.Windows.Ink;
    using System.Windows.Input;
    using System.Windows.Media;
    using System.Windows.Media.Animation;
    using System.Windows.Shapes;

    using System.ComponentModel;
    using System.Collections.ObjectModel;

    namespace Silverlight40.WCFRIAServices.CustomSortingPaging
    {
        
    // 为了实现分页功能,所以需要实现 IPagedCollectionView 接口
        
    // 为了集合具有排序的功能,所以需要继承自 SortableCollectionView<T>
        public class PageableSortableCollectionView<T> : SortableCollectionView<T>, IPagedCollectionView
        {
            
    // 是否允许分页
            public bool CanChangePage
            {
                
    get { return true; ; }
            }

            
    // 页索引是否正在改变
            private bool _isPageChanging;
            
    public bool IsPageChanging
            {
                
    get { return _isPageChanging; }
                
    private set
                {
                    
    if (_isPageChanging != value)
                    {
                        _isPageChanging 
    = value;
                        OnPropertyChanged(
    "IsPageChanging");
                    }
                }
            }

            
    // 项总数
            public int ItemCount
            {
                
    get { return TotalItemCount; }
                
    set { TotalItemCount = value; }
            }

            
    // 页索引
            private int _pageIndex;
            
    public int PageIndex
            {
                
    get { return _pageIndex; }
            }

            
    // 页大小
            private int _pageSize = 10;
            
    public int PageSize
            {
                
    get { return _pageSize; }
                
    set
                {
                    
    if (value != _pageSize && value >= 1)
                    {
                        _pageSize 
    = value;
                        OnPropertyChanged(
    "PageSize");
                    }
                }
            }

            
    // 项总数。未知的话则返回 -1
            private int _totalItemCount;
            
    public int TotalItemCount
            {
                
    get { return _totalItemCount; }
                
    set
                {
                    
    if (value != _totalItemCount)
                    {
                        _totalItemCount 
    = value;
                        OnPropertyChanged(
    "TotalItemCount");
                        OnPropertyChanged(
    "ItemCount");
                    }
                }
            }

            
    // PageIndex 改变之后所触发的事件
            public event EventHandler<EventArgs> PageChanged;

            
    // PageIndex 改变之前所触发的事件
            public event EventHandler<PageChangingEventArgs> PageChanging;

            
    // 将第一页设置为当前页
            public bool MoveToFirstPage()
            {
                
    return MoveToPage(0);
            }

            
    // 将最后一页设置为当前页
            public bool MoveToLastPage()
            {
                
    return TotalItemCount != -1 && PageSize > 0 && MoveToPage(PageCount - 1);
            }

            
    // 将当前页的下一页设置为当前页
            public bool MoveToNextPage()
            {
                
    return MoveToPage(_pageIndex + 1);
            }

            
    // 将指定的页索引设置为当前页
            public bool MoveToPage(int pageIndex)
            {
                
    if (pageIndex < -1)
                    
    return false;
                
    if (pageIndex == -1 && PageSize > 0)
                    
    return false;
                
    if (pageIndex >= PageCount || _pageIndex == pageIndex)
                    
    return false;

                
    try
                {
                    IsPageChanging 
    = true;

                    PageChangingEventArgs args 
    = new PageChangingEventArgs(pageIndex);
                    
    // 触发 PageChanging 事件
                    OnPageChanging(new PageChangingEventArgs(pageIndex));
                    
    // 监听者的 PageChanging 事件处理完成后继续往下执行
                    if (args.Cancel)
                        
    return false;

                    _pageIndex 
    = pageIndex;
                    
                    IsPageChanging 
    = false;

                    OnPropertyChanged(
    "PageIndex");
                    OnPageChanged(EventArgs.Empty);

                    
    base.Refresh();

                    
    return true;
                }
                
    finally
                {
                    IsPageChanging 
    = false;
                }
            }

            
    // 将当前页的上一页设置为当前页
            public bool MoveToPreviousPage()
            {
                
    return MoveToPage(_pageIndex - 1);
            }

            
    protected virtual void OnPageChanging(PageChangingEventArgs args)
            {
                
    if (PageChanging != null)
                    PageChanging(
    this, args);
            }

            
    protected virtual void OnPageChanged(EventArgs args)
            {
                
    if (PageChanged != null)
                    PageChanged(
    this, args);
            }



            
    // 页总数
            public int PageCount
            {
                
    get
                {
                    
    if (_pageSize <= 0)
                        
    return 0;

                    
    return Math.Max(1, (int)Math.Ceiling((double)ItemCount / (double)_pageSize));
                }
            }
        }
    }


    ProductViewModel.cs

    代码
    using System;
    using System.Net;
    using System.Windows;
    using System.Windows.Controls;
    using System.Windows.Documents;
    using System.Windows.Ink;
    using System.Windows.Input;
    using System.Windows.Media;
    using System.Windows.Media.Animation;
    using System.Windows.Shapes;

    using System.ComponentModel;
    using Silverlight40.Web.Model;
    using Silverlight40.Web.Service;
    using System.ServiceModel.DomainServices.Client;
    using System.Collections.Generic;
    using System.Linq;
    using System.Reflection;

    namespace Silverlight40.WCFRIAServices.CustomSortingPaging
    {
        
    public class ProductViewModel : INotifyPropertyChanged
        {
            
    public event PropertyChangedEventHandler PropertyChanged;

            
    // 数据
            public PageableSortableCollectionView<Product> Data { getprivate set; }

            
    // 页大小
            public int PageSize
            {
                
    get { return Data.PageSize; }
                
    set
                {
                    
    if (Data.PageSize == value)
                        
    return;

                    Data.PageSize 
    = value;

                    
    if (PropertyChanged != null)
                        PropertyChanged(
    thisnew PropertyChangedEventArgs("PageSize"));
                }
            }

            
    public ProductViewModel()
            {
                Data 
    = new PageableSortableCollectionView<Product>();

                Data.PageChanging 
    += new EventHandler<PageChangingEventArgs>(Data_PageChanging);
                Data.PageChanged 
    += new EventHandler<EventArgs>(Data_PageChanged);
                Data.Reload 
    += new EventHandler<ReloadEventArgs>(Data_OnReload);

                GetData();
            }

            
    void Data_PageChanging(object sender, PageChangingEventArgs e)
            {
                
            }

            
    void Data_PageChanged(object sender, EventArgs e)
            {

            }

            
    void Data_OnReload(object sender, ReloadEventArgs e)
            {
                
    // 排序或页索引有变化则从服务端获取新的数据
                GetData();
            }

            
    private void GetData()
            {
                MyDomainContext context 
    = new MyDomainContext();

                
    string sort = "";

                
    // 构造排序表达式
                foreach (SortDescription sortDesc in Data.SortDescriptions)
                {
                    
    // “it”是 ObjectQuery<T> 的默认名称
                    sort += string.Format("it.{0} {1},", sortDesc.PropertyName, sortDesc.Direction == ListSortDirection.Ascending ? "asc" : "desc");
                }
                
    if (sort == "")
                    sort 
    = "it.ProductId asc";
                
    else
                    sort 
    = sort.TrimEnd(',');

                
    int take = Data.PageSize;
                
    int skip = Data.PageIndex * Data.PageSize;

                
    // 为了获取数据记录总数,所以需要在这里写分页逻辑
                EntityQuery<Product> query = context.GetProductsBySortQuery(sort).Skip(skip).Take(take);
                
    // 返回数据中是否包含数据记录总数(前提,分页逻辑要写在 EntityQuery<Product> 上)
                query.IncludeTotalCount = true;
                LoadOperation
    <Product> lo = context.Load(query);
                lo.Completed 
    += new EventHandler(delegate 
                {
                    Data.Clear();

                    
    // 数据记录总数
                    Data.ItemCount = lo.TotalEntityCount;

                    
    // 当前页的数据集合
                    foreach (Product p in lo.Entities)
                    {
                        Data.Add(p);
                    }
                });
            }
        }
    }


    Demo.xaml

    代码
    <navigation:Page x:Class="Silverlight40.WCFRIAServices.CustomSortingPaging.Demo" 
               xmlns
    ="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
               xmlns:x
    ="http://schemas.microsoft.com/winfx/2006/xaml" 
               xmlns:d
    ="http://schemas.microsoft.com/expression/blend/2008"
               xmlns:mc
    ="http://schemas.openxmlformats.org/markup-compatibility/2006"
               xmlns:navigation
    ="clr-namespace:System.Windows.Controls;assembly=System.Windows.Controls.Navigation"
               xmlns:sdk
    ="http://schemas.microsoft.com/winfx/2006/xaml/presentation/sdk"
               xmlns:vm
    ="clr-namespace:Silverlight40.WCFRIAServices.CustomSortingPaging"
               Title
    ="Demo Page">
        
    <Grid x:Name="LayoutRoot">
            
    <StackPanel>

                
    <!--
                    在 View 中引入 ViewModel
                
    -->
                
    <StackPanel.DataContext>
                    
    <vm:ProductViewModel />
                
    </StackPanel.DataContext>

                
    <sdk:DataGrid x:Name="dataGrid" AutoGenerateColumns="True" ItemsSource="{Binding Data}" />

                
    <sdk:DataPager x:Name="dataPager" Source="{Binding Data}" PageSize="{Binding PageSize}" DisplayMode="FirstLastPreviousNext" IsEnabled="True" IsTotalItemCountFixed="True" />
                
            
    </StackPanel>
        
    </Grid>
    </navigation:Page>



    OK
    [源码下载]

  • 相关阅读:
    Win32中精确计时器(微秒级)
    一个封装文件操作和目录操作的类
    CString
    两个经典的RGB与YUV转换函数
    C++文件流
    HSI、HSV、RGB、CMY、CMYK、HSL、HSB、Ycc、XYZ、Lab、YUV颜色模型
    MPEG4与H264区别,编码及应用
    C file文件基本知识
    RGB ,YUV, YCbCr的定义
    在android平台上测试C/C++程序及库
  • 原文地址:https://www.cnblogs.com/webabcd/p/1862119.html
Copyright © 2011-2022 走看看