一天,我寫了一個PagingController
類,以幫助分頁,所以在這裏你去:
你將不得不清理源比特b ecause在做一些使用MS代碼契約,他們引用了一些(很基本的)工具的東西從棱鏡等
使用Sample(代碼隱藏 - ViewModel.cs
):
private const int PageSize = 20;
private static readonly SortDescription DefaultSortOrder = new SortDescription("Id", ListSortDirection.Ascending);
private readonly ObservableCollection<Reservation> reservations = new ObservableCollection<Reservation>();
private readonly CollectionViewSource reservationsViewSource = new CollectionViewSource();
public ViewModel()
{
this.reservationsViewSource.Source = this.reservations;
var sortDescriptions = (INotifyCollectionChanged)this.reservationsViewSource.View.SortDescriptions;
sortDescriptions.CollectionChanged += this.OnSortOrderChanged;
// The 5000 here is the total number of reservations
this.Pager = new PagingController(5000, PageSize);
this.Pager.CurrentPageChanged += (s, e) => this.UpdateData();
this.UpdateData();
}
public PagingController Pager { get; private set; }
public ICollectionView Reservations
{
get { return this.reservationsViewSource.View; }
}
private void UpdateData()
{
var currentSort = this.reservationsViewSource.View.SortDescriptions.DefaultIfEmpty(DefaultSortOrder).ToArray();
// This is the "fetch the data" method, the implementation of which
// does not directly interest us for this example.
var data = this.crsService.GetReservations(this.Pager.CurrentPageStartIndex, this.Pager.PageSize, currentSort);
this.reservations.Clear();
this.reservations.AddRange(data);
}
private void OnSortOrderChanged(object sender, NotifyCollectionChangedEventArgs e)
{
if (e.Action == NotifyCollectionChangedAction.Add) {
this.UpdateData();
}
}
使用Sample(XAML - View.xaml
):
<DataGrid ... ItemSource="{Binding Reservations}" />
<!-- all the rest is UI to interact with the pager -->
<StackPanel>
<StackPanel Orientation="Horizontal" HorizontalAlignment="Center" Margin="4">
<StackPanel.Resources>
<Style TargetType="{x:Type Button}">
<Setter Property="FontFamily" Value="Webdings" />
<Setter Property="Width" Value="60" />
<Setter Property="Margin" Value="4,0,4,0" />
</Style>
<Style TargetType="{x:Type TextBlock}">
<Setter Property="Margin" Value="4,0,4,0" />
<Setter Property="VerticalAlignment" Value="Center" />
</Style>
<Style TargetType="{x:Type TextBox}">
<Setter Property="Margin" Value="4,0,4,0" />
<Setter Property="Width" Value="40" />
</Style>
</StackPanel.Resources>
<Button Content="9" Command="{Binding Path=Pager.GotoFirstPageCommand}" />
<Button Content="3" Command="{Binding Path=Pager.GotoPreviousPageCommand}" />
<TextBlock Text="Page" />
<TextBox Text="{Binding Path=Pager.CurrentPage, ValidatesOnExceptions=True}" />
<TextBlock Text="{Binding Path=Pager.PageCount, StringFormat=of {0}}" />
<Button Content="4" Command="{Binding Path=Pager.GotoNextPageCommand}" />
<Button Content=":" Command="{Binding Path=Pager.GotoLastPageCommand}" />
</StackPanel>
<ScrollBar Orientation="Horizontal" Minimum="1" Maximum="{Binding Path=Pager.PageCount}" Value="{Binding Path=Pager.CurrentPage}"/>
</StackPanel>
簡短說明:
正如你看到的,視圖模型並沒有真正做多。它使表示當前頁面項目的集合,並且暴露了CollectionView
(用於數據綁定)和PagingController
到視圖。然後,它是所有更新的集合中的數據項(以及因此CollectionView
中)每次PagingController
表明,事情已經改變。當然,這意味着你需要的是,給定一個起始索引,頁面大小,以及由這些參數來描述數據的SortDescription[]
回報切片的方法。這是你業務邏輯的一部分,我沒有在這裏包含代碼。
在XAML側所有的工作都是通過結合PagingController
完成。我已經公開了這裏的全部功能(綁定到First/Prev/Next/Last命令的按鈕,直接綁定TextBox
到CurrentPage
,並且綁定ScrollBar
到)。通常你不會同時使用所有這些。
來源
2011-03-15 00:47:55
Jon
非常感謝Jon,非常感謝! – Aaron 2011-03-17 15:42:19
這對DataGrid調整大小(並因此更改可見元素的數量? – 2012-07-17 16:37:16
@ChrisKlepeis:不是給定的,但您可以綁定到「PageSize」並註冊爲「PropertyChanged」,因此我沒有看到當然,尋呼機並不是要有效地覆蓋這種情況,所以perf就不會那麼好。 – Jon 2012-07-17 17:25:19