最开始的情况:
希望的效果:
方法1:我修改了DataGrid的样式,是可以达到目的,不过要配好外面的DataPager来确定位置,如果DataPager的宽度改变了,那么就需要手动再去修改Style里滚动条位置(不过一般情况也不会去修改~)。
方法2:在外面创建一个ScrollBar然后通过这个滚动条来控制表格的滚动。
想到了绑定,不过直接在DataGrid的属性里貌似找不到他的滚动条。搜到个函数可以找到对象,但是在前台和后台都尝试绑定却依旧控制不了(拖动DataGrid的滚动条,外置的会跟着动),于是再搜索,终于在一个的网友的文章里找到了同样的问题,不过他写的好简略而且没有给出源代码。我来补充吧。
用于获得和同步Scroll的扩展类:
DataGridScrollExtensions
public static class DataGridScrollExtensions { /// <summary> /// 枚举,横向滚动条/纵向滚动条 /// </summary> public enum ScrollMode { Vertical, Horizontal } /// <summary> /// 把滚动条至于最前端。 /// <param name="mode"></param> public static void ScrollToStart(this DataGrid grid, ScrollMode mode) { switch (mode) { case ScrollMode.Vertical: grid.ScrollToPercent(ScrollMode.Vertical, 0); break; case ScrollMode.Horizontal: grid.ScrollToPercent(ScrollMode.Horizontal, 0); break; } } /// <summary> /// 把滚动条至于最后端。 /// </summary> /// <param name="mode"></param> public static void ScrollToEnd(this DataGrid grid, ScrollMode mode) { switch (mode) { case ScrollMode.Vertical: grid.ScrollToPercent(ScrollMode.Vertical, 100); break; case ScrollMode.Horizontal: grid.ScrollToPercent(ScrollMode.Horizontal, 100); break; } } /// <summary> /// 把滚动条至于指定位置。 /// </summary> /// <param name="mode"></param> /// <param name="percent"></param> public static void ScrollToPercent(this DataGrid grid, ScrollMode mode, double percent) { if (percent < 0) percent = 0; else if (percent > 100) percent = 100; var scrollProvider = GetScrollProvider(grid); //滚动 switch (mode) { case ScrollMode.Vertical: scrollProvider.SetScrollPercent(System.Windows.Automation.ScrollPatternIdentifiers.NoScroll, percent); break; case ScrollMode.Horizontal: scrollProvider.SetScrollPercent(percent, System.Windows.Automation.ScrollPatternIdentifiers.NoScroll); break; } } /// <summary> /// 获取滚动条当前位置。 /// </summary> /// <param name="mode"></param> /// <returns></returns> public static double GetScrollPosition(this DataGrid grid, ScrollMode mode) { var scrollBar = grid.GetScrollbar(mode); return scrollBar.Value; } /// <summary> /// 获取滚动条最大值。 /// </summary> /// <param name="mode"></param> /// <returns></returns> public static double GetScrollMaximum(this DataGrid grid, ScrollMode mode) { var scrollBar = grid.GetScrollbar(mode); return scrollBar.Maximum; } /// <summary> /// 设置滚动条到指定位置。 /// </summary> /// <param name="mode"></param> /// <param name="position"></param> public static void Scroll(this DataGrid grid, ScrollMode mode, double position) { var scrollBar = grid.GetScrollbar(mode); double positionPct = ((position / scrollBar.Maximum) * 100); grid.ScrollToPercent(mode, positionPct); } /// <summary> /// 获取滚动条。 /// </summary> /// <param name="element"></param> /// <returns></returns> private static IScrollProvider GetScrollProvider(DataGrid grid) { var p = FrameworkElementAutomationPeer.FromElement(grid) ?? FrameworkElementAutomationPeer.CreatePeerForElement(grid); return p.GetPattern(PatternInterface.Scroll) as IScrollProvider; } /// <summary> /// 在指定的DataGrid中指定需要找到的滚动条(横/纵)。 /// </summary> /// <param name="grid"></param> /// <param name="mode"></param> /// <returns></returns> public static ScrollBar GetScrollbar(this DataGrid grid, ScrollMode mode) { if (mode == ScrollMode.Vertical) return grid.GetScrollbar("VerticalScrollbar"); else return grid.GetScrollbar("HorizontalScrollbar"); } /// <summary> /// 在指定的DataGrid中找到他的Scroll。 /// </summary> /// <typeparam name="T"></typeparam> /// <param name="dep"></param> /// <returns></returns> private static ScrollBar GetScrollbar(this DependencyObject dep, string name) { for (int i = 0; i < VisualTreeHelper.GetChildrenCount(dep); i++) { var child = VisualTreeHelper.GetChild(dep, i); if (child != null && child is ScrollBar && ((ScrollBar)child).Name == name) return child as ScrollBar; else { ScrollBar sub = GetScrollbar(child, name); if (sub != null) return sub; } } return null; } }
<toolkit:DockPanel > <toolkit:DockPanel toolkit:DockPanel.Dock="Bottom" Height="26"> <sdk:DataPager x:Name="dataPager" PageSize="13" Width="173" FontFamily="Tahoma" toolkit:DockPanel.Dock="Right"/> <ScrollBar x:Name="scorllBar1" Height="24" Orientation="Horizontal" ViewportSize="10"/> </toolkit:DockPanel> <sdk:DataGrid x:Name="dataGrid" AutoGenerateColumns="False" IsReadOnly="True" AlternatingRowBackground="AntiqueWhite" Background="#FFE0DEDE" toolkit:DockPanel.Dock="Top"> <sdk:DataGrid.Columns> <sdk:DataGridTextColumn Header="机构" Binding="{Binding JG}"/> <sdk:DataGridTextColumn Header="办理柜员" Binding="{Binding BLGY}"/> <sdk:DataGridTextColumn Header="业务" Binding="{Binding YW}"/> <sdk:DataGridTextColumn Header="票号" Binding="{Binding PH}"/> <sdk:DataGridTextColumn Header="到达时间" Binding="{Binding DDSJ}"/> <sdk:DataGridTextColumn Header="办理时间" Binding="{Binding BLSJ}"/> <sdk:DataGridTextColumn Header="结束时间" Binding="{Binding JSSJ}"/> <sdk:DataGridTextColumn Header="等待时长" Binding="{Binding DDSC}"/> <sdk:DataGridTextColumn Header="服务时长" Binding="{Binding FWSC}"/> <sdk:DataGridTextColumn Header="驻留时长" Binding="{Binding ZLSC}"/> <sdk:DataGridTextColumn Header="业务状态" Binding="{Binding YWZT}"/> <sdk:DataGridTextColumn Header="评价" Binding="{Binding PJ}"/> </sdk:DataGrid.Columns> </sdk:DataGrid> </toolkit:DockPanel>PS:DockPanel是属于Silverlight Toolkit的控件, 确认你安装了Silverlight Toolkit.再引用System.windows.control。
后台CS:
1、设置DataPager
PagedCollectionView itemListView = new PagedCollectionView(new dataSourceList()); dataGrid.ItemsSource = itemListView; dataPager.Source = itemListView;PS:dataSourceList是DateGrid的数据源,我前面有写http://blog.csdn.net/wushang923/article/details/7168820
2、设置ScrollBar
/// <summary> /// 尝试通过VistualTree来找到Scrollbar对象 /// </summary> private void TryUseVisualTree() { EventHandler h = null; ScrollBar scroll = null; //在LayoutUpated里操作能确保数据加载完成,这样下面的设置才不会出错。 dataGrid.LayoutUpdated += h = delegate { if (scroll == null) { scroll = DataGridScrollExtensions.GetScrollbar(dataGrid, DataGridScrollExtensions.ScrollMode.Horizontal); if (scroll != null) { //一旦找到注销LayoutUpdated事件 dataGrid.LayoutUpdated -= h; //隐藏原来DataGrid里的滚动条。 scroll.Opacity = 0; //设置外置滚动条最大值。 scorllBar1.Maximum = scroll.Maximum; //设置外置滚动条最小改变值。 scorllBar1.SmallChange= 20; //滚动条滚动位移量设为原有位移量的0.9倍。 scorllBar1.ViewportSize = scroll.ViewportSize * 0.9; //执行同步 scorllBar1.ValueChanged += new RoutedPropertyChangedEventHandler<double>(scroll_ValueChanged); } } }; } /// <summary> /// 值改变的响应函数。 /// </summary> /// <param name="sender"></param> /// <param name="e"></param> void scroll_ValueChanged(object sender, RoutedPropertyChangedEventArgs<double> e) { this.dataGrid.Scroll(DataGridScrollExtensions.ScrollMode.Horizontal, e.NewValue); }PS:因为最后需要把DataGrid的滚动条隐藏起来,所以不能用scorllBar1直接获取DataGrid的滚动条。
Demo下载地址:点击打开链接