0

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はそれらのメソッドを使用してサイズ/ページなどを決定することを読んだと思いました。

4

2 に答える 2

1

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

DataPager.Sourceプロパティから:

ソースは、任意の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;
于 2011-01-28T19:40:56.463 に答える
0

WCFRIAサービスを使用していることに気づきました。より単純なシナリオでは、DataGridとDataPagerの両方をDomainDataSourceにバインドするだけで、何も実装する必要はありません。しかし、あなたにはもっと複雑な要件があったと思います。それが、すべてを手作業で行っている理由です。

于 2011-09-28T12:22:26.843 に答える