获得datagrid自带滚动条,实现两个datagrid同步滚动



由于有个需求,需要把一个datagrid作为复杂表头,一个datagrid作为内容

在内容datagrid滚动时,作为表头的datagird同步滚动


datagrid自带滚动条,但是我们不能直接获取datagrid的滚动条,不能对滚动条事件进行操作

我们需要重新一个datagrid,以便我们可以取到datagrid的滚动条,进行一些操作


自己重写后的DataGrid在xmlns:mx="clr-namespace:UH.Service"引用后

可以直接使用<mx:MyDataGrid x:Name="headerDataGrid" Visibility="Collapsed">

public class MyDataGrid:DataGrid
    {
        public ScrollBar verticalScrollbar;
        public ScrollBar horizontalScrollbar;
        public MyDataGrid needDG { get; set; }//传一个在该datagrid滚动时需要同步滚动的的datagrid
        public MyDataGrid()
        {
        }


        public override void OnApplyTemplate()  //得到datagrid的滚动条时需要重写OnApplyTemplate方法
        {
            base.OnApplyTemplate();//需要调用父类的OnApplyTemplate方法
            //得到datagrid里边的滚动条
            verticalScrollbar = base.GetTemplateChild("VerticalScrollbar") as ScrollBar;
            horizontalScrollbar = base.GetTemplateChild("HorizontalScrollbar") as ScrollBar;


            horizontalScrollbar.Scroll += new ScrollEventHandler(horizontalScrollbar_Scroll);//为滚动条增加事件
        }


        //为得到的滚动条增加滚动事件
        void horizontalScrollbar_Scroll(object sender, ScrollEventArgs e)
        {
            if (needDG!=null)
            {

                //需要同步滚动的滚动条进行滚动,如果直接设置滚动条的value滚动条会动但是界面不会更着动
                needDG.Scroll(ScrollMode.Horizontal,e.NewValue);
            }
        }

    }

   //以下是datagird滚动条工具类,实现传value界面随滚动条滚动
    public enum ScrollMode
    {
        Vertical = 0,
        Horizontal = 1
    }


    public static class DataGridScrollExtensions 
    {
        // Scroll to the start of the ScrollBar.
        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;
            }
        }


        // Scroll to the end of the ScrollBar.
        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;
            }
        }


        // Scroll to a percentage of the scrollbar (50% = half).
        public static void ScrollToPercent
        (this DataGrid grid, ScrollMode mode, double percent)
        {
            // Fix the percentage.
            if (percent < 0)
                percent = 0;
            else if (percent > 100)
                percent = 100;


            // Get the scroll provider.
            var scrollProvider = GetScrollProvider(grid);


            // Scroll.
            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;
            }
        }


        // Get the current position of the scrollbar.
        public static double GetScrollPosition(this DataGrid grid, ScrollMode mode)
        {
            var scrollBar = grid.GetScrollbar(mode);
            return scrollBar.Value;
        }


        // Get the maximum position of a scrollbar.
        public static double GetScrollMaximum(this DataGrid grid, ScrollMode mode)
        {
            var scrollBar = grid.GetScrollbar(mode);
            return scrollBar.Maximum;
        }


        // Scroll to a position of the scrollbar.
        public static void Scroll(this DataGrid grid, ScrollMode mode, double position)
        {
            // Get the scrollbar and convert the position to percent.
            var scrollBar = grid.GetScrollbar(mode);
            double positionPct = ((position / scrollBar.Maximum) * 100);


            // Scroll to a specific percentage of the scrollbar.
            grid.ScrollToPercent(mode, positionPct);
        }


        // Get a scroll provider for the grid.
        private static IScrollProvider GetScrollProvider(DataGrid grid)
        {
            var p = FrameworkElementAutomationPeer.FromElement(grid) ??
            FrameworkElementAutomationPeer.CreatePeerForElement(grid);
            return p.GetPattern(PatternInterface.Scroll) as IScrollProvider;
        }


        // Get one of the grid's scrollbars.
        public static ScrollBar GetScrollbar(this DataGrid grid, ScrollMode mode)
        {
            if (mode == ScrollMode.Vertical)
                return grid.GetScrollbar("VerticalScrollbar");
            else
                return grid.GetScrollbar("HorizontalScrollbar");
        }


        // Find the scrollbar for our datagrid.
        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;
        }
    } 

   最后同步滚动实现了,但是上边作为表头的datagrid需要把滚动条隐藏掉

   但是如果直接把他隐藏掉滚动条本身也就消失了,一个流氓办法把下边

   显示内容的datagrid的margin设置成"0,-20,0,0"也就是距离顶部20就把他挡住了

   

   还有就是滚动到最后时由于显示内容的datagrid会存在垂直的滚动条,会有一点点错误

   我们可以把作为复杂表头的datagrid,也绑定一行,在想办法把他隐藏掉就行了

   

  



  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值