先给控件添加两个属性:AllowTabbedPager和UnSelectedTabColor属性。AllowTabbedPager属性可以启用一种新的带选项卡的页面导航模式,而UnSelectedTabColor属性则说明了未选中选项卡的背景颜色。这里我们将未选中选项卡的前景色设置为页面导航的前景色。
为了使页面导航看起来有选项卡风格,我们只需要对颜色和边框调整一下,而不需要修改网格导航的内置逻辑。
... {
get ...{return Convert.ToBoolean(ViewState["AllowTabbedPager"]);}
set
...{
ViewState["AllowTabbedPager"]=value;
if(value)
...{
//Force some layout properties
cellSpacing=0;
cellPadding=0;
//Force the pager to be numeric and stay on top
PagerStyle.Mode=PagerMode.NumericPages;
PagerStyle.Position=PagerPosition.Top;
}
}
}
public Color UnSelectedTabColor
... {
get ...{return (Color) (ViewState["UnSelectedTabColor"]);}
set
...{
ViewState["UnSelectedTabColor"]=value;
}
}
当设置AllowTabbedPager属性时,我们需要强制设定其他一些属性。特别地,页面导航模式必须是NumericPages,而且页面导航必须位于顶部位置。而且,我们还需要将单元格边距和间隔设置为零以获得更好的图形效果。由于单元格边距和间隔是影响整个网格的属性,如果将他们设置为非零值,则AllowTabbedPager可能会导致图形问题,此时用户可以尝试通过使用针对单独列的宽度、高度和边距样式等属性来进行局部弥补。
支持新的页面导航风格同时还意味着需要对ItemCreated事件处理程序进行一些轻微的修改。
... {
if(e.Item.ItemType==ListItemType.Pager)
CustomizePager(e);
if(e.Item.ItemType==ListItemType.Footer)
SetupFooter(e);
}
private void CustomizePager(DataGridItemEventArgs e)
... {
if(this.PagerStyle.Mode==PagerMode.NextPrev)
...{
SetupNextPrevPager(e);
return;
}
if(this.AllowTabbedPager)
...{
SetupTabbedPager(e);
return;
}
}
将数值风格的页面导航栏转变为选项卡风格的核心代码位于SetupTabbedPager方法中,如以下代码所示:
... {
TableCell pager=(TableCell) e.Item.Controls[0];
//Enumerates all the items in the pager
for(int i=0;i<pager.Controls.Count;i++)
...{
object o=pager.Controls[i];
//Unselected tabs
if(o is LinkButton)
...{
LinkButton lb=(LinkButton) o;
//Modify text
lb.Text="<span style=margin:2>Page"+lb.Text+"</span>";
//Modify styles
lb.BorderWidth=Unit.Pixel(1);
lb.BorderColor=Color.White;
lb.BackColor=UnselectedTabColor;
lb.BorderStyle=BorderStyle.Outset;
//Use hard-coded height (should be changed!)
lb.Height=Unit.Pixel(18);
}
else
...{
//select tab
if(o is Label)
...{
Label l=(Label) o;
//Modify text
l.Text="<span style=margin:2>Page"+l.Text+"</span>";
//Modify styles
l.Font.Bold=true;
l.BackColor=HeaderStyle.BackColor;
l.BorderWidth=Unit.Pixel(1);
//must express a .net color as an html string
string htmlColor=HeaderStyle.BackColor.Name;
if(htmlColor.StartsWith("ff"))
htmlColor=htmlColor.Replace("ff","#");
//draw border around the selected page
string borderString=htmlColor+"outset 1px";
l.Style["border-top"]=borderString;
l.Style["border-left"]=borderString;
l.Style["border-rigth"]=borderString;
l.Style["border-bottom-color"]=htmlColor;
//use hard-coded height(should be changed!)
//make the current tag slightly taller
l.Height=Unit.Pixel(20);
}
else
...{
if(o is LiteralControl)
...{
//remove unneeded spacing
LiteralControl lc=(LiteralControl) o;
lc.Text="";
}
}
}
}
}
SetupTabbedPager方法遍历惟一的<td>元素的所有子控件,该元素代表了DataGrid控件的页面导航。Controls集合可以包含三种类型的控件:LinkButton、Label和LiteralControl。特别地,有多少个页面需要访问(除了当前页面之外),就需要多少个LinkButton对象;我们还需要一个Label控件来表示当前所选中的页面;一个空白的文字控件来分隔其他的控件。我们将链接按钮呈现为未选中的选项卡,并将文字控件的文本修改为空字符串,以使选项卡之间看起来显得紧凑。
关于HTML颜色字符串值需要说明一点:为了使已选中的选项卡的视觉效果看起来象真的选项卡,我们需要创建一个连续的区域,其中包括DataGrid标题和所选中的选项卡。不过,由于他们是不同的HTML元素,因此需要一点技巧。我们使用与标题背景相同的颜色来绘制<span>标记(代表标签)的底部边框。不过,我们无法设置控件的底部边框风格,必须求助于Style集合中的CSS设置。标题的背景色是一个名为Color的.net framework类。如果使用了某种常用的颜色,我们可以很容易的将它转换为一个HTML浏览器可用的字符串。不过,如果背景色是使用RGB要素-#rrggbb字符串,由Color.Name属性所返回的字符串具有以下格式:ffrrggbb。该字符串是不能被浏览器所理解的,因此我们需要将ff的前缀去掉。