你的位置:首页 > ASP.net教程

[ASP.net教程][Silverlight] 分离C1FlexGrid滚动条


一  场景介绍

Silverlight 5.0的C1FlexGrid控件里自带的滚动条,是嵌入在C1FlexGrid宽度和高度的范围里的,效果如下图所示:

image(未隐藏自带滚动条)     image(隐藏自带的滚动条)

其中行高的定义如下:

<c1:C1FlexGrid x:Name="flxg" Width="300" Height="200"        Grid.Row="0" HeadersVisibility="None"        AlternatingRowBackground="AliceBlue" Background="LightGray"        GridLinesVisibility="All" GridLinesBrush="Black">  <c1:C1FlexGrid.Rows>    <c1:Row Height="100" />    <c1:Row Height="100" />  </c1:C1FlexGrid.Rows>  <c1:C1FlexGrid.Columns>    <c1:Column Width="100" />    <c1:Column Width="100" />    <c1:Column Width="100" />  </c1:C1FlexGrid.Columns></c1:C1FlexGrid>

即使把C1FlexGrid的行、宽设置成所有 行高和 或所有 列宽和,自带的滚动条还是会显示出来,但实际上如果隐藏掉C1FlexGrid自带的滚动条,效果就好看多了,所以我就想把C1FlexGrid自带的滚动条隐藏掉,然后在下方或右侧加一个自己的滚动条,来操作滚动C1FlexGrid。

二  解决思路

1、C1FlexGrid的属性ScrollPosition可以获取或设置其自带的滚动条的偏移量;

2、C1FlexGrid中与滚动有关的事件有,ScrollPositionChanging和ScrollPositionChanged,断点调试实验一下即可知道当执行到ScrollPositionChanged事件时,C1FlexGrid的ScrollPosition属性值更新为滚动条的偏移量;

3、当C1FlexGrid触发ScrollPositionChanged事件时,更新自定义滚动条(ScrollBar)的偏移值;自定义滚动条(ScrollBar)的ValueChanged事件触发时,更新C1FlexGrid的ScrollPosition属性值;

4、注意C1FlexGrid的ScrollPosition属性为负,ScrollBar的Value属性值为正,注意正负转换;

5、ScrollBar的Maximum属性:设置滚动条可滑动的最大值,应等于C1FlexGrid可视范围之外的长度或宽度值;

6、ScrollBar的ViewportSize属性:设置滚动条上白条的长度值,应该等于C1FlexGrid的宽度值,即可视范围的长度或宽度值;

三  部分代码

根据C1FlexGrid初始化滚动条

 1 /// <summary> 2 /// 根据C1FlexGrid初始化滚动条 3 /// </summary> 4 /// <param name="flexGrid"></param> 5 private void InitScrollbar(C1FlexGrid flexGrid) 6 { 7 	double allColumnsWidth = 0; 8 	double allRowsHeight = 0; 9 	foreach (Column col in flexGrid.Columns) 10 	{ 11 		allColumnsWidth += col.Width.Value; 12 	} 13 	foreach (Row row in flexGrid.Rows) 14 	{ 15 		allRowsHeight += row.Height; 16 	} 17 	// 当所有行高和大于C1FlexGrid框的高度,则纵向滚动条可用 18 	if (allRowsHeight > flexGrid.Height) 19 	{ 20 		scrollbarVert.Visibility = Visibility.Visible; 21 		// 纵向滚动条的最大值应该是C1FlexGrid中超出可见范围剩余的高度 22 		scrollbarVert.Maximum = allRowsHeight - flexGrid.Height; 23 		// 滚动条上白条的长度应该是C1FlexGrid可见范围的高度 24 		scrollbarVert.ViewportSize = flexGrid.Height; 25 		scrollbarHori.SmallChange = 1;// 滚动改变的最小值 26 	} 27 	else 28 	{ 29 		scrollbarVert.Visibility = Visibility.Collapsed; 30 	} 31 	// 当所有列宽和大于C1FlexGrid框的宽度,则横向滚动条可用 32 	if (allColumnsWidth > flexGrid.Width) 33 	{ 34 		scrollbarHori.Visibility = Visibility.Visible; 35 		// 横向滚动条的最大值应该是C1FlexGrid中超出可见范围剩余的宽度 36 		scrollbarHori.Maximum = allColumnsWidth - flexGrid.Width; 37 		// 滚动条上白条的长度应该是C1FlexGrid可见范围的宽度 38 		scrollbarHori.ViewportSize = flexGrid.Width; 39 		scrollbarHori.SmallChange = 1;// 滚动改变的最小值 40 	} 41 	else 42 	{ 43 		scrollbarHori.Visibility = Visibility.Collapsed; 44 	} 45 }

View Code

C1FlexGrid触发滚动事件

 1 // C1FlexGrid的滚动事件 2 private void flxg_ScrollPositionChanged(object sender, EventArgs e) 3 { 4 	Point position = flxg.ScrollPosition;// C1FlexGrid当前滚动条的位置 5 	txtMsg1.Text = "C1FlexGrid: " + position.X + "," + position.Y; 6 	// 更新自定义滚动条 7 	scrollbarHori.Value = -position.X; 8 	scrollbarVert.Value = -position.Y; 9 }

View Code

横/纵滚动条滑动事件

 1 // 横向滚动条 2 private void scrollbarHori_ValueChanged(object sender, RoutedPropertyChangedEventArgs<double> e) 3 { 4 	// 注意,滚动条控件Scrollbar的value值是正数,与C1FlexGrid的滚动条位置正好相反 5 	flxg.ScrollPosition = new Point(-scrollbarHori.Value, flxg.ScrollPosition.Y); 6 } 7  8 // 纵向滚动条 9 private void scrollbarVert_ValueChanged(object sender, RoutedPropertyChangedEventArgs<double> e) 10 { 11 	// 注意,滚动条控件Scrollbar的value值是正数,与C1FlexGrid的滚动条位置正好相反 12 	flxg.ScrollPosition = new Point(flxg.ScrollPosition.X, -scrollbarVert.Value); 13 }

View Code

四  后话

C1FlexGrid在ScrollBar部分我觉得做的并不精致,当把C1FlexGrid的长、宽设置成完全等于所有行高和、所有列宽和时,如上面所说C1FlexGrid自带的滚动条会显示出来,如果这时候要完全显示C1FlexGrid右下角那个单元格时,滚动条的偏移量为(-3,-3);

所以如果按照我上面的代码执行,然后再把自定义的两个滚动条拉到最下面或最右侧,此时C1FlexGrid的滚动条偏移量还差3,如下图所示:

image滚动条拉到极端时偏移量显示为(-200,-150)

image 最后一个单元格完全显示时,偏移量显示为(-203,-153)

所以实际上在给自定义滚动条ScrollBar设置最大偏移值时,应另外加3,即scrollbarVert.Maximum = allRowsHeight - flexGrid.Height + 3;

这样就完全同步了;

五  资源下载

源代码Sample工程下载 http://files.cnblogs.com/files/memento/SLC1FlexGridScorllbar.2015.03.20.zip