WPF分页DataGrid

最近用到WPF的表格控件,需要使用分页功能,找了很多例子都不是很满意。有些是模仿SL做的DataPager导航条,使用的时候还要和DataGrid组合使用,不是很方便。最好还是继承DataGrid的分页表格控件。 于是自己动手封装了一个分页表格。
见图例:
WPF分页DataGrid_第1张图片
先说思路,然后说实现。
为什么要使用分页这里不是讨论话题,分页表格需要知道两个结果:总记录数和分页数据集,所以必须暴露Total和ItemsSource属性,要查询分页必须传递:页面和每页记录数。
1.分页表格是一个DataGrid,所以继承于DataGrid;
2.添加一些依赖属性,比如:页面、每页记录数等,允许用户自定义设置属性;
3.重写样式,在样式模板中添加分页导航控件;
4.暴露分页事件,用户分页逻辑在事件中实现。
说起来很容易,做起来没一个很容易的。为了分页导航按钮漂亮,我还做了一个ImageButton的用户控件(这里不介绍此控件)

看看部分实现:
1.定义表格模板(比较复杂,不具体一一说明了)
关键在ControlTemplate中加入一个Grid,就是导航控件部分,注意我的绑定方式,不是TemplateBinding。

<Style x:Key="{x:Type local:PagingDataGrid}" TargetType="{x:Type local:PagingDataGrid}">
	<Setter Property="Background"
		      Value="{DynamicResource {x:Static SystemColors.ControlBrushKey}}"/>
	<Setter Property="Foreground"
		      Value="{DynamicResource {x:Static SystemColors.ControlTextBrushKey}}"/>
	<Setter Property="BorderBrush" Value="#FF688CAF" />
	<Setter Property="BorderThickness" Value="1" />
	<Setter Property="RowDetailsVisibilityMode" Value="VisibleWhenSelected" />
	<Setter Property="ScrollViewer.CanContentScroll"
		      Value="true"/>
	<Setter Property="ScrollViewer.PanningMode"
		Value="Both"/>
	<Setter Property="Stylus.IsFlicksEnabled"
		Value="False"/>
	<Setter Property="Template">
	    <Setter.Value>
		<ControlTemplate TargetType="{x:Type local:PagingDataGrid}">
		    <Border Background="{TemplateBinding Background}"
		      BorderBrush="{TemplateBinding BorderBrush}"
		      BorderThickness="{TemplateBinding BorderThickness}"
		      SnapsToDevicePixels="True"
		      Padding="{TemplateBinding Padding}">
			<Grid>
			    <Grid.RowDefinitions>
				<RowDefinition Height="*" />
				<RowDefinition Height="Auto" />
			    </Grid.RowDefinitions>
			    <ScrollViewer Grid.Row="0"   
				Focusable="false"
				Name="DG_ScrollViewer">
				<ScrollViewer.Template>
				……
			    </ScrollViewer>
			    
			    <!--分页控件-->
			    <Grid Grid.Row="1" Visibility="{Binding IsShowPaging,RelativeSource={RelativeSource TemplatedParent},Converter={StaticResource visibilityConverter}}">
				<Grid.ColumnDefinitions>
				    <ColumnDefinition Width="Auto" />
				    <ColumnDefinition />
				    <ColumnDefinition Width="Auto" />
				</Grid.ColumnDefinitions>
				<ComboBox Grid.Column="0"  VerticalAlignment="Center" x:Name="PART_PageSizeList"
				      MinWidth="40" Margin="5,0,0,0"
				      ItemsSource="{Binding PageSizeItemsSource,RelativeSource={RelativeSource TemplatedParent},Mode=TwoWay}" 
				      SelectedItem="{Binding PageSize,RelativeSource={RelativeSource TemplatedParent},Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}" />
				<StackPanel Grid.Column="1" VerticalAlignment="Center" Orientation="Horizontal" Margin="5,0,0,0">

				    <local:ImageButton x:Name="PART_FirstPage"
					ImageSource="/CustomControlLibrary;component/Images/pagination_first.gif" 
					GrayImageSource="/CustomControlLibrary;component/Images/pagination_first_gray.gif" />
				    <local:ImageButton x:Name="PART_PerviousPage"
					ImageSource="/CustomControlLibrary;component/Images/pagination_prev.gif" 
					GrayImageSource="/CustomControlLibrary;component/Images/pagination_prev_gray.gif" />

				    <TextBlock Text="Page "  VerticalAlignment="Center"/>
				    <TextBox Width="30" Text="{Binding PageIndex,RelativeSource={RelativeSource TemplatedParent},Mode=TwoWay}" x:Name="PART_PageIndex" />
				    <TextBlock Text=" of "  VerticalAlignment="Center"/>
				    <TextBlock Text="{Binding PageCount,RelativeSource={RelativeSource TemplatedParent},Mode=OneWay}"  VerticalAlignment="Center"/>

				    <local:ImageButton x:Name="PART_NextPage"
					ImageSource="/CustomControlLibrary;component/Images/pagination_next.gif" 
					GrayImageSource="/CustomControlLibrary;component/Images/pagination_next_gray.gif" />
				    <local:ImageButton x:Name="PART_LastPage"
					ImageSource="/CustomControlLibrary;component/Images/pagination_last.gif" 
					GrayImageSource="/CustomControlLibrary;component/Images/pagination_last_gray.gif" />
				    <local:ImageButton x:Name="PART_Refresh"
					ImageSource="/CustomControlLibrary;component/Images/pagination_load.png" />
				</StackPanel>
				<TextBlock Grid.Column="2" VerticalAlignment="Center" Margin="5,0,5,0" >
				    Display <TextBlock Text="{Binding Start,RelativeSource={RelativeSource TemplatedParent},Mode=OneWay}" /> to <TextBlock Text="{Binding End,RelativeSource={RelativeSource TemplatedParent},Mode=OneWay}" /> of <TextBlock Text="{Binding Total,RelativeSource={RelativeSource TemplatedParent},Mode=OneWay}" /> items
				</TextBlock>
			    </Grid>
			</Grid>
		    </Border>
		</ControlTemplate>
	    </Setter.Value>
	</Setter>
	<Style.Triggers>
	    <Trigger Property="IsGrouping" Value="true">
		<Setter Property="ScrollViewer.CanContentScroll" Value="false"/>
	    </Trigger>
	</Style.Triggers>
</Style>




2.分页表格类(部分代码,完整见下载中的代码)
其中定义了一些依赖属性,如:PageIndex、PageSize、Total等

public class PagingDataGrid : DataGrid {

    static PagingDataGrid() {
        DefaultStyleKeyProperty.OverrideMetadata(typeof(PagingDataGrid), new FrameworkPropertyMetadata(typeof(PagingDataGrid)));
    }

    #region 依赖属性
    public int Total {
        get { return (int)GetValue(TotalProperty); }
        set { SetValue(TotalProperty, value); }
    }

    /// <summary>
    /// 总记录数
    /// </summary>
    public static readonly DependencyProperty TotalProperty =
        DependencyProperty.Register("Total", typeof(int), typeof(PagingDataGrid), new UIPropertyMetadata(0));



    public int PageSize {
        get { return (int)GetValue(PageSizeProperty); }
        set { SetValue(PageSizeProperty, value); }
    }

    /// <summary>
    /// 每页记录数,默认:10
    /// </summary>
    public static readonly DependencyProperty PageSizeProperty =
        DependencyProperty.Register("PageSize", typeof(int), typeof(PagingDataGrid), new UIPropertyMetadata(10));



    public int PageIndex {
        get { return (int)GetValue(PageIndexProperty); }
        set { SetValue(PageIndexProperty, value); }
    }

    /// <summary>
    /// 当前页码,默认:1
    /// </summary>
    public static readonly DependencyProperty PageIndexProperty =
        DependencyProperty.Register("PageIndex", typeof(int), typeof(PagingDataGrid), new UIPropertyMetadata(1));


    public static readonly RoutedEvent PagingChangedEvent = EventManager.RegisterRoutedEvent("PagingChangedEvent", RoutingStrategy.Bubble, typeof(PagingChangedEventHandler), typeof(PagingDataGrid));

    #endregion

    #region 重写方法
    public override void OnApplyTemplate() {
        base.OnApplyTemplate();

        //获取模板中的控件
	//添加控件事件
    }

    #endregion

    #region 分页事件
    #endregion
}



3.用户界面使用,和DataGrid一样使用,增加几个属性就行了

<Window x:Class="WpfApplication.MainWindow2"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:lib="clr-namespace:CustomControlLibrary;assembly=CustomControlLibrary"
        Name="self"
        Title="MainWindow2" Height="325" Width="518">
    <Grid>
        <lib:PagingDataGrid 
            PageSizeList="10,20,30"
            ItemsSource="{Binding Result.Students,ElementName=self}" 
            Total="{Binding Result.Total,ElementName=self}" 
            PagingChanged="PagingDataGrid_PagingChanged">
            <lib:PagingDataGrid.Columns>
                <DataGridTextColumn Header="Name" Binding="{Binding Name}" />
                <DataGridTextColumn Header="Age" Binding="{Binding Age}" />
                <DataGridTextColumn Header="Gender" Binding="{Binding Gender}" />
            </lib:PagingDataGrid.Columns>
        </lib:PagingDataGrid>
    </Grid>
</Window>


4.分页实现,只需要触发事件PagingDataGrid_PagingChanged事件即可

    /// <summary>
    /// MainWindow2.xaml 的交互逻辑
    /// </summary>
    public partial class MainWindow2 : Window {
        public MainWindow2() {
            Result = new StuResult();
            InitializeComponent();
        }

        public StuResult Result { get; set; }

        public void Query(int size, int pageIndex) {
            Result.Total = Student.Students.Count;
            Result.Students = Student.Students.Skip((pageIndex - 1) * size).Take(size).ToList();

        }

        private void PagingDataGrid_PagingChanged(object sender, CustomControlLibrary.PagingChangedEventArgs args) {
            Query(args.PageSize, args.PageIndex);
        }
    }



代码见我的资源中,下载地址:http://download.csdn.net/detail/qing2005/4337197。


你可能感兴趣的:(datagrid,header,Class,WPF,textbox,binding)