Sliverlight,为DataGrid添加外置的滚动条(ScrollBar)和分页(DataPager)

最开始的情况:

Sliverlight,为DataGrid添加外置的滚动条(ScrollBar)和分页(DataPager)_第1张图片

希望的效果:

Sliverlight,为DataGrid添加外置的滚动条(ScrollBar)和分页(DataPager)_第2张图片

方法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;
        }
    }

前台Xaml:
    <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下载地址:点击打开链接



你可能感兴趣的:(datagrid,header,silverlight,scroll,binding,Sliverlight)