由于有个需求,需要把一个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,也绑定一行,在想办法把他隐藏掉就行了