2011-01-28 1 views
0

私はSilverlight用のデータグリッドとデータページャを含むMVVMに優しいページを作成しようとしています。私のviewmodelで、私はDataPagerが私のTotalItemCountを拾わないのはなぜですか?

public class DiscountViewModel : INotifyPropertyChanged, IPagedCollectionView 

IPagedCollectionViewインタフェースを実装していると私はITEMCOUNT個とTotalItemCountを取得するために必要なすべてのメソッドを実装しました。

public bool CanChangePage { 
     get { return TotalItemCount > PageIndex * PageSize; } 
    } 

    public bool IsPageChanging { 
     get { return false; } 
    } 

    public int ItemCount { 
     get { return itemCount; } 
     set { itemCount = value; RaisePropertyChange("ItemCount"); } 
    } 

    public bool MoveToFirstPage() { 
     PageChanging(this, new PageChangingEventArgs(PageIndex)); 
     PageIndex = 0; 
     PageChanged(this, null); 
     return true; 
    } 

    public bool MoveToLastPage() { 
     throw new NotImplementedException(); 
    } 

    public bool MoveToNextPage() { 
     PageChanging(this, new PageChangingEventArgs(PageIndex)); 
     PageIndex++; 
     PageChanged(this, null); 
     return true; 
    } 

    public bool MoveToPage(int pageIndex) { 
     PageChanging(this, new PageChangingEventArgs(PageIndex)); 
     PageIndex = pageIndex; 
     PageChanged(this, null); 
     return true; 
    } 

    public bool MoveToPreviousPage() { 
     PageChanging(this, new PageChangingEventArgs(PageIndex)); 
     PageIndex--; 
     PageChanged(this, null); 
     return true; 
    } 

    public event EventHandler<EventArgs> PageChanged; 

    public event EventHandler<PageChangingEventArgs> PageChanging; 

    public int PageIndex { 
     get { return pageIndex; } 
     set { pageIndex = value; RaisePropertyChange("PageIndex"); } 
    } 

    public int PageSize { 
     get { return pageSize; } 
     set { pageSize = value; RaisePropertyChange("PageSize"); } 
    } 

    public int TotalItemCount { 
     get { return totalItemCount; } 
     set { totalItemCount = value; RaisePropertyChange("TotalItemCount"); } 
    } 

XAMLは、アイテムにバインドするために正常に動作しているとデータグリッドは最初にロードされ、最初の5つの項目が表示されます。 (すべての割引の合計数のための5項目について返さ及び9)割引を取得し、すべてが実行され、数字は私が期待するものに出てくる合計数を設定するためのrelaventコードが

<data:DataGrid x:Name="discountsDataGrid" ItemsSource="{Binding Discounts, Mode=TwoWay}" MinHeight="200" AutoGenerateColumns="False" SelectedItem="{Binding SelectedDiscount, Mode=TwoWay}"> 
        <i:Interaction.Triggers> 
         <i:EventTrigger EventName="RowEditEnded"> 
          <i:InvokeCommandAction Command="{Binding SaveChangesCommand}" CommandParameter="{Binding SelectedDiscount}" /> 
         </i:EventTrigger> 
        </i:Interaction.Triggers> 

        <data:DataGrid.Columns> 
         <data:DataGridTextColumn Header="Name" Binding="{Binding Name}" /> 
         <data:DataGridTextColumn Header="Discount Amount" Binding="{Binding Amount}" /> 
        </data:DataGrid.Columns> 
       </data:DataGrid> 
       <sdk:DataPager PageSize="{Binding PageSize}" Source="{Binding Path=ItemsSource, ElementName=discountsDataGrid}" Margin="0,-1,0,0" /> 

public void LoadDiscounts(Object parameter){ 
     EntityQuery<Discount> eq = ctx.GetPagedDiscountsQuery(PageIndex, PageSize, ""); 
     eq.IncludeTotalCount = true; 
     ctx.Load<Discount>(eq, OnDiscountsLoaded, null); 
    } 

    private void OnDiscountsLoaded(LoadOperation<Discount> loadOperation) { 
     if (loadOperation.Error != null) { 

     } else { 
      Discounts = loadOperation.Entities; 
      ItemCount = loadOperation.TotalEntityCount; 
      ctx.GetDiscountCount(OnCountCompleted, null); 
      RaisePropertyChange("Discounts"); 
     } 
    } 

    private void OnCountCompleted(InvokeOperation<int> op) { 
     TotalItemCount = op.Value; 
     RaisePropertyChange("Discounts"); 
     RaisePropertyChange("TotalItemCount"); 
    } 

しかし、データキャプチャでは5つ以上の割引があるとは思われません。 TotalItemCountが正しく設定されていることがわかります。これについての奇妙なことは、TotalItemCountプロパティは、値を設定する以外の他のコードでは呼び出されないということです。前の/次へ/最初/最後のボタンをクリックできるかどうかを判断するためにdatapagerを使用してはいけませんか?

更新私はMouseEnterイベントを購読しているときにDataPagerを見て、面白いものを見つけました。 ItemCountは5で、ViewModelに何を設定しても(たとえば、手動で9に設定するなど)、DataPagerはそのコレクション内のアイテムを調べて、実際にいくつのアイテムが存在するかを判断します。これらの値はViewModelクラスから読み取られません。周囲のコンテキストがIPagedCollectionViewを実装している場合、DataPagerがこれらのメソッドを使用してサイズ/ページ/などを決定すると、私はそれを読んでいると思いました。

答えて

1

DataPagerコントロールSourceプロパティをコレクションにバインドする必要があります。 DataGridコントロールのItemsSourceプロパティではありません。 DataPager.Source propertyから

供給源は、任意のIEnumerableを 収集することができます。 IPagedCollectionViewを実装していないIEnumerableにバインドされた場合、DataPager は、すべてのデータが単一ページの にあるかのように動作します。 DataPager のプロパティを設定しても、コントロールには影響しません( )。

通常、ソースはIPagedCollectionViewを実装するコレクション です。 IPagedCollectionViewは ページング機能を提供し、 DataPagerコントロールは IPagedCollectionViewと対話するためのユーザー インターフェイスを提供します。 IEnumerableコレクションにページング機能を提供するには、 をPagedCollectionViewクラスにラップすることができます。

List<String> itemList = new List<String>(); 
// Generate some items to add to the list. 
for (int i = 1; i <= 33; i++) 
{ 
    System.Text.StringBuilder sb = new System.Text.StringBuilder("Item "); 
    sb.Append(i.ToString()); 
    itemList.Add(sb.ToString()); 
} 
// Wrap the itemList in a PagedCollectionView for paging functionality 
PagedCollectionView itemListView = new PagedCollectionView(itemList); 

// Set the DataPager and ListBox to the same data source. 
dataPager1.Source = itemListView; 
listBox1.ItemsSource = itemListView; 
+0

あなたの答えはかなり近いです。私のViewModelは実際の基になるコレクション(私の場合はIListだけ)の代わりにIPagedCollectionViewインターフェイスを実装していました。それで、あなたは正しい方向に私を指差してくれました。 – Josh

0

私はあなたがWCF RIA Servicesを使用していることに気づきました。簡単なシナリオでは、DataGridとDataPagerの両方をDomainDataSourceにバインドするだけで、何も実装する必要はありません。しかし、私はあなたがより複雑な要件を持っていたと思うので、あなたは手ですべてをやっているのです。

関連する問題