闲来无事,用WPF实现了一个分页功能,利用MVVM设计模式。
Model:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using ListView.Service;
namespace ListView.Models
{
public class PerSonModel:NotificationObject
{
private string name = string.Empty;
public string Name
{
set { name = value;}
get { return name; }
}
private string id = string.Empty;
public string ID
{
set { id = value; }
get { return id; }
}
private string age;
public string Age
{
set { age = value; }
get { return age; }
}
private string sex = string.Empty;
public string Sex
{
set { sex = value; }
get { return sex; }
}
private string addr = string.Empty;
public string Addr
{
set { addr = value; }
get { return addr; }
}
private string telephone = string.Empty;
public string Telephone
{
set { telephone = value; }
get { return telephone; }
}
}
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Collections.ObjectModel;
using ListView.Models;
using ListView.Service;
using System.Xml;
using System.Threading.Tasks;
namespace ListView.ViewModels
{
public class ViewModel : NotificationObject
{
private static long id = 0;
public event Action InvalidPage;
#region property
private List<PerSonModel> personist = new List<PerSonModel>(); //保存所有<span style="font-family: Arial, Helvetica, sans-serif;">PerSonModel</span>数据
public List<PerSonModel> PerSonList
{
set
{
personist = value;
RaisePropertyChanged("TotalSize");
}
get { return personist; }
}
private ObservableCollection<PerSonModel> currentshowlist = new ObservableCollection<PerSonModel>();
public ObservableCollection<PerSonModel> CurrentShowList <span style="font-family: Arial, Helvetica, sans-serif;">//当前显示在DataGrid中的数据</span>
{
set { currentshowlist = value; }
get { return currentshowlist; }
}
private List<PerSonModel> tlist = new List<PerSonModel>();
public List<PerSonModel> Tlist <span style="font-family: Arial, Helvetica, sans-serif;">//对应Xml中的数据</span>
{
set { tlist = value; }
get { return tlist; }
}
private long totalpagesize;
public long TotalPageSize //总页数
{
set
{
totalpagesize = value;
RaisePropertyChanged("TotalPageSize");
if (totalpagesize > 0)
{
CurrentPage = 1;
}
}
get
{
return totalpagesize;
}
}
private readonly long pagesize = 30;
public long PageSize //每页数据
{
get { return pagesize; }
}
private long currentpage;
public long CurrentPage
{
set
{
if (value > 0 && value <= TotalPageSize)
{
currentpage = value;
if (value == 1)
{
IsPreviousEnabled = false;
}
else
{
IsPreviousEnabled = true;
}
IsNextPageEnabled = true;
RaisePropertyChanged("CurrentPage");
}
if (value >= TotalPageSize)
{
IsPreviousEnabled = true;
IsNextPageEnabled = false;
}
}
get { return currentpage; }
}
private bool isnextpageisenabled;
public bool IsNextPageEnabled <span style="font-family: Arial, Helvetica, sans-serif;">//下一页按钮是否可用</span>
{
set { isnextpageisenabled = value; RaisePropertyChanged("IsNextPageEnabled"); }
get { return isnextpageisenabled; }
}
private bool ispreviouspageenabled;
public bool IsPreviousEnabled /<span style="font-family: Arial, Helvetica, sans-serif;">/上一页按钮是否可用</span>
{
set { ispreviouspageenabled = value; RaisePropertyChanged("IsPreviousEnabled"); }
get { return ispreviouspageenabled; }
}
private string inputpage;
public string InputPage //文本框输入的页码
{
set
{
long gopage;
if (long.TryParse(value,out gopage))
{
inputpage = value;
RaisePropertyChanged("InputPage");
}
else
{
OnInvalidPage();
}
}
get { return inputpage; }
}
private RelayCommand nextpagecommond;
public RelayCommand NextPageCommand
{
get
{
if (nextpagecommond == null)
{
nextpagecommond = new RelayCommand(SwitchToNextPage);
}
return nextpagecommond;
}
}
private RelayCommand previouspagecommand;
public RelayCommand PreviousCommand
{
get
{
if (previouspagecommand == null)
{
previouspagecommand = new RelayCommand(SwitchToPreviousPage);
}
return previouspagecommand;
}
}
private RelayCommand gocommand;
public RelayCommand GoCommand //跳转到对应的页码
{
get
{
if (gocommand == null)
{
gocommand = new RelayCommand(GoInputPage);
}
return gocommand;
}
}
#endregion property
#region Event
public void OnInvalidPage()
{
if (InvalidPage != null)
{
InvalidPage();
}
}
#endregion
public ViewModel()
{
InitPersonList();
}
private void InitPersonList() //初始化,从Xml中获取数据,由于数据比较少,反复添加
{
XmlDocument doc = new XmlDocument();
doc.Load(@"../../Datas/PerSon.xml");
XmlNode root = doc.SelectSingleNode("/PerSons");
if (root.HasChildNodes)
{
XmlNodeList nodelist = doc.SelectNodes("/PerSons/PerSon");
foreach (XmlNode node in nodelist)
{
PerSonModel person = new PerSonModel()
{
Name = node.Attributes["Name"].Value,
ID = (++id).ToString(),
Age = node.Attributes["Age"].Value,
Sex = node.Attributes["Sex"].Value,
Addr = node.Attributes["Addr"].Value,
Telephone = node.Attributes["Tel"].Value
};
PerSonList.Add(person);
Tlist.Add(person);
}
}
for (int i = 0; i < 1000; i++)
{
for (int j = 0; j < Tlist.Count; j++)
{
PerSonModel person = new PerSonModel()
{
Name = Tlist[j].Name,
ID = (++id).ToString(),
Age = Tlist[j].Age,
Sex = Tlist[j].Sex,
Addr = Tlist[j].Addr,
Telephone = Tlist[j].Telephone
};
PerSonList.Add(person);
}
}
if (PerSonList.Count % PageSize == 0)
{
TotalPageSize = PerSonList.Count / PageSize;
}
else
{
TotalPageSize = PerSonList.Count / PageSize + 1;
}
if (PerSonList.Count > PageSize)
{
for (int i = 0; i < PageSize; i++)
{
CurrentShowList.Add(PerSonList[i]);
}
}
else
{
for (int i = 0; i < PerSonList.Count; i++)
{
CurrentShowList.Add(PerSonList[i]);
}
}
}
private void SwitchToNextPage()
{
++CurrentPage;
GetList(CurrentPage - 1);
}
private void SwitchToPreviousPage()
{
--CurrentPage;
GetList(CurrentPage - 1);
}
private void GetList(long index)
{
CurrentShowList.Clear();
var query = from person in PerSonList select person;
var collection = query.Skip((int)(index * PageSize)).Take((int)PageSize);
foreach (var p in collection)
{
CurrentShowList.Add(p);
}
}
private void GoInputPage()
{
long gopage;
if (long.TryParse(InputPage, out gopage))
{
if (gopage >= 1 && gopage <= TotalPageSize)
{
CurrentPage = gopage;
GetList(CurrentPage - 1);
}
else
{
OnInvalidPage();
}
}
}
}
}
<Window x:Class="ListView.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow" Height="400" Width="525">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="5*"/>
<RowDefinition/>
</Grid.RowDefinitions>
<DataGrid x:Name="pList" AutoGenerateColumns="False" CanUserAddRows="False">
<DataGrid.Columns>
<DataGridTextColumn Header="Name" Width="60" Binding="{Binding Name}"/>
<DataGridTextColumn Header="ID" Width="60" Binding="{Binding ID}"/>
<DataGridTextColumn Header="Age" Width="50" Binding="{Binding Age}"/>
<DataGridTextColumn Header="Sex" Width="50" Binding="{Binding Sex}"/>
<DataGridTextColumn Header="Tel" Width="100" Binding="{Binding Telephone}"/>
<DataGridTextColumn Header="Address" Width="Auto" Binding="{Binding Addr}"/>
</DataGrid.Columns>
</DataGrid>
<Grid Grid.Row="1">
<Grid.ColumnDefinitions>
<ColumnDefinition/>
<ColumnDefinition/>
<ColumnDefinition/>
<ColumnDefinition/>
<ColumnDefinition/>
</Grid.ColumnDefinitions>
<StackPanel Orientation="Horizontal">
<Label Width="30" Margin="20,20,0,10" Content="{Binding CurrentPage}"/>
<Label Width="15" Margin="0,20,0,10" Content="/"/>
<Label Width="30" Margin="0,20,40,10" Content="{Binding TotalPageSize}"/>
</StackPanel>
<Button Grid.Column="1" Width="80" Height="30" Content="上一页" IsEnabled="{Binding IsPreviousEnabled}" Command="{Binding PreviousCommand}"/>
<Button Grid.Column="2" Width="80" Height="30" Content="下一页" IsEnabled="{Binding IsNextPageEnabled}" Command="{Binding NextPageCommand}"/>
<TextBox Grid.Column="3" Width="80" Height="25" Text="{Binding InputPage}"/>
<Button Grid.Column="4" Width="50" Height="30" Content="Go" Command="{Binding GoCommand}"/>
</Grid>
</Grid>
</Window>
Xaml后端:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using ListView.ViewModels;
namespace ListView
{
/// <summary>
/// MainWindow.xaml 的交互逻辑
/// </summary>
public partial class MainWindow : Window
{
ViewModel vm = new ViewModel();
public MainWindow()
{
InitializeComponent();
vm.InvalidPage += InvalidPage;
this.DataContext = vm;
pList.ItemsSource = vm.CurrentShowList;
}
private void InvalidPage() //输入非法值提示
{
MessageBox.Show("请输入正确的页码!");
}
}
}
Xml:提供数据
<?xml version="1.0" encoding="utf-8" ?>
<PerSons>
<PerSon Name = "刘明浩" Age = "25" Sex = "Male" Tel = "15111009988" Addr = "河南省洛阳市"/>
<PerSon Name = "黄花" Age = "21" Sex = "Male" Tel = "13119080010" Addr = "安徽省黄山市"/>
<PerSon Name = "李珍" Age = "25" Sex = "Female" Tel = "13220981234" Addr = "上海市静安区"/>
</PerSons>
Service辅助类:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.ComponentModel;
namespace ListView.Service
{
public class NotificationObject : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
public void RaisePropertyChanged(string propertyName)
{
if (this.PropertyChanged != null)
{
this.PropertyChanged.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
}
}
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows.Input;
namespace ListView.Service
{
public class RelayCommand : ICommand
{
public RelayCommand(Action execute)
: this(execute, null)
{
}
public RelayCommand(Action execute, Func<bool> canExecute)
{
if (execute == null)
throw new ArgumentNullException("execute");
_execute = execute;
_canExecute = canExecute;
}
public bool CanExecute(object parameter)
{
return _canExecute == null ? true : _canExecute();
}
public event EventHandler CanExecuteChanged
{
add
{
if (_canExecute != null)
CommandManager.RequerySuggested += value;
}
remove
{
if (_canExecute != null)
CommandManager.RequerySuggested -= value;
}
}
public void Execute(object parameter)
{
_execute();
}
readonly Action _execute;
readonly Func<bool> _canExecute;
}
}