Почему DataPager не забирает мой TotalItemCount? - PullRequest
0 голосов
/ 28 января 2011

Я пытаюсь создать дружественную к MVVM страницу, которая содержит сетку данных и пейджер данных для Silverlight. На моей модели представления я реализовал интерфейс 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 работает нормально для привязки к элементам, а сетка данных показывает первые пять элементов при первоначальной загрузке.

<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 никогда не вызывается никаким другим кодом, кроме как для установки значения. Не должен ли пейджер данных использовать это, чтобы определить, можно ли нажимать кнопки «Предыдущая / Следующая / Первая / Последняя»?

Обновление Поэтому я посмотрел на DataPager, подписываясь на событие MouseEnter, и обнаружил кое-что интересное. ItemCount равен 5, и независимо от того, что я установил в ViewModel (например, установив его на 9 вручную), DataPager просматривает только элементы в своей коллекции, чтобы определить, сколько элементов на самом деле там. Он не читает эти значения из класса ViewModel. Я думал, что прочитал, что если окружающий контекст реализует IPagedCollectionView, то DataPager будет использовать эти методы для определения размера / страницы / и т. Д.

Ответы [ 2 ]

1 голос
/ 28 января 2011

Свойство DataPager Source должно быть привязано к коллекции.Не свойство ItemsSource элемента управления DataGrid.

From Свойство DataPager.Source :

Источником может быть любая коллекция IEnumerable.При связывании с IEnumerable, который не реализует IPagedCollectionView, 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 голосов
/ 28 сентября 2011

Я заметил, что вы используете службы WCF RIA. В более простых сценариях вы можете просто связать ваш DataGrid и DataPager с DomainDataSource, и вам не придется ничего реализовывать. Но я думаю, что у вас было более сложное требование, и поэтому вы все делаете вручную.

...