Silverlightのデータグリッドとデータページャーを含むMVVM対応のページを作成しようとしています。ビューモデルに、IPagedCollectionViewインターフェイスを実装しました
public class DiscountViewModel : INotifyPropertyChanged, 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つのアイテムが表示されます。
<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" />
割引を取得して合計数を設定するための関連コードがすべて実行され、数は私が期待するものになります(返されたアイテムの場合は5、すべての割引の合計数の場合は9)
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プロパティが、値を設定することを除いて、他のコードによって呼び出されることは決してないということです。データページャーはそれを使用して、[前へ]、[次へ]、[最初]、[最後]のボタンをクリックできるかどうかを判断するべきではありませんか?
更新 それで、MouseEnterイベントをサブスクライブしているときにDataPagerを見て、何か面白いものを見つけました。ItemCountは5であり、ViewModelで何に設定しても(たとえば、手動で9に設定しても)、DataPagerはコレクション内のアイテムのみを調べて、実際に存在するアイテムの数を判別します。ViewModelクラスからこれらの値を読み取っていません。周囲のコンテキストがIPagedCollectionViewを実装している場合、DataPagerはそれらのメソッドを使用してサイズ/ページなどを決定することを読んだと思いました。