本GridView参考国外的一篇文章而来,并在原来的基础上面加以改进而成,先看图:
但是有个非常不爽的地方,就是GridView要进行回发操作,所以,点击或者展开折叠节点,都会进行数据的回发。
实现的原理是这样的,首先看一下绑定到GridView的datatable数据表格:
可以看到本数据集的构造方式,即parentID下面保存的都是父ID的节点,而ChildID为空;但是当某行数据为子类时,父类的ParentID置空,而ChildID则存入子类ID值。这样,把这个数据集赋值给GridView的时候,稍微处理就可以达到开始的图片效果了,具体操作如下:
首先,需要在GridView的首列添加两个ImageButton按钮,分别为“MinBT”(-)和“PluseBT”(+),还包括一个image标签。然后就是在RowCreated的时候,将GridView的行值赋值给imagebutton的commandargument属性,同时将datatable中数据的前两行ParentID和ChildID隐藏掉,具体代码如下:
protected
void
GridView1_RowCreated(
object
sender, GridViewRowEventArgs e)
{
if
(e.Row.RowType
==
DataControlRowType.Header)
{
e.Row.Cells[
1
].Visible
=
false
;
e.Row.Cells[
2
].Visible
=
false
;
}
if
(e.Row.RowType
==
DataControlRowType.DataRow)
{
e.Row.Cells[
1
].Visible
=
false
;
e.Row.Cells[
2
].Visible
=
false
;
ImageButton btnMin
=
(ImageButton)e.Row.Cells[
0
].FindControl(
"
MinBT
"
);
btnMin.CommandArgument
=
e.Row.RowIndex.ToString();
ImageButton btnAdd
=
(ImageButton)e.Row.Cells[
0
].FindControl(
"
PluseBT
"
);
btnAdd.CommandArgument
=
e.Row.RowIndex.ToString();
}
}
然后,就是对按钮进行处理了,让有子节点的父类显示“+”按钮,而让没有子节点的父类显示“-”按钮,这需要在GridView1_RowDataBound事件中处理,具体代码如下:
protected
void
GridView1_RowDataBound(
object
sender, GridViewRowEventArgs e)
{
if
(e.Row.RowType
==
DataControlRowType.DataRow)
{
string
ShowHide
=
e.Row.Cells[
1
].Text;
ShowHide
=
ShowHide.Replace(
"
"
,
""
);
ShowHide
=
ShowHide.Replace(
"
"
,
""
);
if
(ShowHide.Trim().Length
==
0
) //如果有子类,前面就会有空白,替换掉后,长度为0,反之则不为0
{
ImageButton btnMin
=
(ImageButton)e.Row.Cells[
0
].FindControl(
"
MinBT
"
);
btnMin.Visible
=
false
; //不显示已展开按钮
ImageButton btnAdd
=
(ImageButton)e.Row.Cells[
0
].FindControl(
"
PluseBT
"
);
btnAdd.Visible
=
false
; //不显示可展开按钮
HtmlImage Line
=
(HtmlImage)e.Row.Cells[
0
].FindControl(
"
Line
"
);
Line.Visible
=
true
; //显示虚线框
}
else
{
HtmlImage Line
=
(HtmlImage)e.Row.Cells[
0
].FindControl(
"
Line
"
);
Line.Visible
=
false
; //反之,则不现实虚线框
}
}
}
然后就是处理按钮的点击事件了:
protected
void
GridView1_RowCommand(
object
sender, GridViewCommandEventArgs e)
{
if
(e.CommandName
==
"
_Show
"
) //当点击展开按钮时
{
int
index
=
Convert.ToInt32(e.CommandArgument); //获取第几行
GridViewRow row
=
GridView1.Rows[index];
int
G_Count
=
GridView1.Rows.Count; //查出总行数
for
(
int
i
=
index
+
1
; i
<
G_Count; i
++
) //从本行下面一行开始
{
if
(GridView1.Rows[i].Cells[
1
].Text
==
"
"
) //如果遇见是子类
{
GridView1.Rows[i].Visible
=
true
; //那么本行显示
}
else //如果遇见的不是子类
{
ImageButton Bt_Min
=
(ImageButton)row.Cells[
0
].FindControl(
"
MinBT
"
);
Bt_Min.Visible
=
true
; //那么已展开按钮显示
ImageButton Bt_plus
=
(ImageButton)row.Cells[
0
].FindControl(
"
PluseBT
"
);
Bt_plus.Visible
=
false
; //未展开按钮隐藏
break
;
}
ImageButton Bt_Min1
=
(ImageButton)row.Cells[
0
].FindControl(
"
MinBT
"
);
Bt_Min1.Visible
=
true
;
ImageButton Bt_plus1
=
(ImageButton)row.Cells[
0
].FindControl(
"
PluseBT
"
);
Bt_plus1.Visible
=
false
;
}
}
if
(e.CommandName
==
"
_Hide
"
)
{
int
index
=
Convert.ToInt32(e.CommandArgument);
GridViewRow row
=
GridView1.Rows[index];
int
G_Count
=
GridView1.Rows.Count;
for
(
int
i
=
index
+
1
; i
<
G_Count; i
++
)
{
if
(GridView1.Rows[i].Cells[
1
].Text
==
"
"
)
{
GridView1.Rows[i].Visible
=
false
;
}
else
{
ImageButton Bt_Min
=
(ImageButton)row.Cells[
0
].FindControl(
"
MinBT
"
);
Bt_Min.Visible
=
false
;
ImageButton Bt_plus
=
(ImageButton)row.Cells[
0
].FindControl(
"
PluseBT
"
);
Bt_plus.Visible
=
true
;
break
;
}
ImageButton Bt_Min1
=
(ImageButton)row.Cells[
0
].FindControl(
"
MinBT
"
);
Bt_Min1.Visible
=
false
;
ImageButton Bt_plus1
=
(ImageButton)row.Cells[
0
].FindControl(
"
PluseBT
"
);
Bt_plus1.Visible
=
true
;
}
}
所有代码如下:
using
System;
using
System.Collections.Generic;
using
System.Linq;
using
System.Web;
using
System.Web.UI;
using
System.Web.UI.WebControls;
using
System.Data;
using
System.Data.SqlClient;
using
System.Web.UI.HtmlControls;
public
partial
class
Default2 : System.Web.UI.Page
{
public
string
connStr
=
System.Configuration.ConfigurationManager.AppSettings[
"
connStr
"
];
protected
void
Page_Load(
object
sender, EventArgs e)
{
if
(
!
IsPostBack)
{
using
(SqlConnection conn
=
new
SqlConnection(connStr))
{
conn.Open();
string
sql
=
"
SELECT ParentName,ParentID,dateof FROM TreeParent tp
"
;
SqlCommand cmd
=
new
SqlCommand(sql, conn);
DataTable dt
=
new
DataTable();
dt.Columns.Add(
new
DataColumn(
"
ParentID
"
,
typeof
(
string
)));
dt.Columns.Add(
new
DataColumn(
"
ChildID
"
,
typeof
(
string
)));
dt.Columns.Add(
new
DataColumn(
"
Name
"
,
typeof
(
string
)));
dt.Columns.Add(
new
DataColumn(
"
Dateof
"
,
typeof
(
string
)));
SqlDataReader sdr
=
cmd.ExecuteReader();
while
(sdr.Read())
{
DataRow dr
=
dt.NewRow();
int
pID
=
Convert.ToInt32(sdr[
"
ParentID
"
]);
dr[
"
ParentID
"
]
=
(sdr[
"
ParentID
"
]);
dr[
"
ChildID
"
]
=
null
;
dr[
"
Name
"
]
=
sdr[
"
ParentName
"
];
dr[
"
Dateof
"
]
=
sdr[
"
Dateof
"
];
dt.Rows.Add(dr);
DataTable myDT
=
GenerateDT(pID.ToString());
foreach
(DataRow drChild
in
myDT.Rows)
{
DataRow drChildDT
=
dt.NewRow();
drChildDT[
"
ChildID
"
]
=
drChild[
"
ChildID
"
];
drChildDT[
"
Name
"
]
=
drChild[
"
ChildName
"
];
drChildDT[
"
Dateof
"
]
=
drChild[
"
Dateof
"
];
dt.Rows.Add(drChildDT);
}
}
sdr.Close();
GridView1.DataSource
=
dt;
GridView1.DataBind();
}
}
}
protected
DataTable GenerateDT(
string
ParentID)
{
using
(SqlConnection conn
=
new
SqlConnection(connStr))
{
conn.Open();
DataTable dt
=
new
DataTable();
dt.Columns.Add(
new
DataColumn(
"
ChildName
"
,
typeof
(
string
)));
dt.Columns.Add(
new
DataColumn(
"
ChildID
"
,
typeof
(
string
)));
dt.Columns.Add(
new
DataColumn(
"
Dateof
"
,
typeof
(
string
)));
string
sql
=
"
SELECT childID,childName,dateof FROM TreeChild tc where tc.ParentID=
"
+
ParentID;
SqlCommand cmd
=
new
SqlCommand(sql, conn);
SqlDataReader sdr
=
cmd.ExecuteReader();
while
(sdr.Read())
{
DataRow dr
=
dt.NewRow();
dr[
"
ChildName
"
]
=
sdr[
"
childName
"
];
dr[
"
ChildID
"
]
=
sdr[
"
ChildID
"
];
dr[
"
Dateof
"
]
=
sdr[
"
Dateof
"
];
dt.Rows.Add(dr);
}
sdr.Close();
return
dt;
}
}
protected
void
GridView1_RowCreated(
object
sender, GridViewRowEventArgs e)
{
if
(e.Row.RowType
==
DataControlRowType.Header)
{
e.Row.Cells[
1
].Visible
=
false
;
e.Row.Cells[
2
].Visible
=
false
;
}
if
(e.Row.RowType
==
DataControlRowType.DataRow)
{
e.Row.Cells[
1
].Visible
=
false
;
e.Row.Cells[
2
].Visible
=
false
;
ImageButton btnMin
=
(ImageButton)e.Row.Cells[
0
].FindControl(
"
MinBT
"
);
btnMin.CommandArgument
=
e.Row.RowIndex.ToString();
ImageButton btnAdd
=
(ImageButton)e.Row.Cells[
0
].FindControl(
"
PluseBT
"
);
btnAdd.CommandArgument
=
e.Row.RowIndex.ToString();
}
}
protected
void
GridView1_RowDataBound(
object
sender, GridViewRowEventArgs e)
{
if
(e.Row.RowType
==
DataControlRowType.DataRow)
{
string
ShowHide
=
e.Row.Cells[
1
].Text;
ShowHide
=
ShowHide.Replace(
"
"
,
""
);
ShowHide
=
ShowHide.Replace(
"
"
,
""
);
if
(ShowHide.Trim().Length
==
0
)
{
ImageButton btnMin
=
(ImageButton)e.Row.Cells[
0
].FindControl(
"
MinBT
"
);
btnMin.Visible
=
false
;
ImageButton btnAdd
=
(ImageButton)e.Row.Cells[
0
].FindControl(
"
PluseBT
"
);
btnAdd.Visible
=
false
;
HtmlImage Line
=
(HtmlImage)e.Row.Cells[
0
].FindControl(
"
Line
"
);
Line.Visible
=
true
;
}
else
{
HtmlImage Line
=
(HtmlImage)e.Row.Cells[
0
].FindControl(
"
Line
"
);
Line.Visible
=
false
;
}
}
}
protected
void
GridView1_RowCommand(
object
sender, GridViewCommandEventArgs e)
{
if
(e.CommandName
==
"
_Show
"
)
{
int
index
=
Convert.ToInt32(e.CommandArgument);
GridViewRow row
=
GridView1.Rows[index];
int
G_Count
=
GridView1.Rows.Count;
for
(
int
i
=
index
+
1
; i
<
G_Count; i
++
)
{
if
(GridView1.Rows[i].Cells[
1
].Text
==
"
"
)
{
GridView1.Rows[i].Visible
=
true
;
}
else
{
ImageButton Bt_Min
=
(ImageButton)row.Cells[
0
].FindControl(
"
MinBT
"
);
Bt_Min.Visible
=
true
;
ImageButton Bt_plus
=
(ImageButton)row.Cells[
0
].FindControl(
"
PluseBT
"
);
Bt_plus.Visible
=
false
;
break
;
}
ImageButton Bt_Min1
=
(ImageButton)row.Cells[
0
].FindControl(
"
MinBT
"
);
Bt_Min1.Visible
=
true
;
ImageButton Bt_plus1
=
(ImageButton)row.Cells[
0
].FindControl(
"
PluseBT
"
);
Bt_plus1.Visible
=
false
;
}
}
if
(e.CommandName
==
"
_Hide
"
)
{
int
index
=
Convert.ToInt32(e.CommandArgument);
GridViewRow row
=
GridView1.Rows[index];
int
G_Count
=
GridView1.Rows.Count;
for
(
int
i
=
index
+
1
; i
<
G_Count; i
++
)
{
if
(GridView1.Rows[i].Cells[
1
].Text
==
"
"
)
{
GridView1.Rows[i].Visible
=
false
;
}
else
{
ImageButton Bt_Min
=
(ImageButton)row.Cells[
0
].FindControl(
"
MinBT
"
);
Bt_Min.Visible
=
false
;
ImageButton Bt_plus
=
(ImageButton)row.Cells[
0
].FindControl(
"
PluseBT
"
);
Bt_plus.Visible
=
true
;
break
;
}
ImageButton Bt_Min1
=
(ImageButton)row.Cells[
0
].FindControl(
"
MinBT
"
);
Bt_Min1.Visible
=
false
;
ImageButton Bt_plus1
=
(ImageButton)row.Cells[
0
].FindControl(
"
PluseBT
"
);
Bt_plus1.Visible
=
true
;
}
}
}
}
前台代码如下:
<%
@ Page Language
=
"
C#
"
AutoEventWireup
=
"
true
"
CodeFile
=
"
Default2.aspx.cs
"
Inherits
=
"
Default2
"
%>
<!
DOCTYPE html PUBLIC
"
-//W3C//DTD XHTML 1.0 Transitional//EN
"
"
http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd
"
>
<
html xmlns
=
"
http://www.w3.org/1999/xhtml
"
>
<
head runat
=
"
server
"
>
<
title
></
title
>
</
head
>
<
body
>
<
form id
=
"
form1
"
runat
=
"
server
"
>
<
div
>
<
asp:GridView ID
=
"
GridView1
"
runat
=
"
server
"
AutoGenerateColumns
=
"
False
"
CellPadding
=
"
4
"
ForeColor
=
"
#333333
"
GridLines
=
"
None
"
onrowcommand
=
"
GridView1_RowCommand
"
onrowcreated
=
"
GridView1_RowCreated
"
onrowdatabound
=
"
GridView1_RowDataBound
"
Width
=
"
456px
"
>
<
RowStyle BackColor
=
"
#F7F6F3
"
ForeColor
=
"
#333333
"
/>
<
Columns
>
<
asp:TemplateField HeaderText
=
"
操作
"
>
<
ItemTemplate
>
<
asp:ImageButton ID
=
"
PluseBT
"
runat
=
"
server
"
Visible
=
"
false
"
CommandName
=
"
_Show
"
BackColor
=
"
White
"
BorderStyle
=
"
none
"
ImageUrl
=
"
~/plus.gif
"
/>
<
asp:ImageButton ID
=
"
MinBT
"
runat
=
"
server
"
CommandName
=
"
_Hide
"
BackColor
=
"
White
"
BorderStyle
=
"
none
"
ImageUrl
=
"
~/minus.gif
"
/>
<
img id
=
"
Line
"
runat
=
"
server
"
visible
=
"
false
"
src
=
"
~/line.gif
"
/>
</
ItemTemplate
>
</
asp:TemplateField
>
<
asp:BoundField DataField
=
"
ParentID
"
HeaderText
=
"
Parent Id
"
/>
<
asp:BoundField DataField
=
"
ChildId
"
HeaderText
=
"
Child Id
"
/>
<
asp:BoundField DataField
=
"
Name
"
HeaderText
=
"
名称
"
/>
<
asp:BoundField DataField
=
"
Dateof
"
HeaderText
=
"
时间
"
/>
</
Columns
>
<
FooterStyle BackColor
=
"
#5D7B9D
"
Font
-
Bold
=
"
True
"
ForeColor
=
"
White
"
/>
<
PagerStyle BackColor
=
"
#284775
"
ForeColor
=
"
White
"
HorizontalAlign
=
"
Center
"
/>
<
SelectedRowStyle BackColor
=
"
#E2DED6
"
Font
-
Bold
=
"
True
"
ForeColor
=
"
#333333
"
/>
<
HeaderStyle BackColor
=
"
#5D7B9D
"
Font
-
Bold
=
"
True
"
ForeColor
=
"
White
"
/>
<
EditRowStyle BackColor
=
"
#999999
"
/>
<
AlternatingRowStyle BackColor
=
"
White
"
ForeColor
=
"
#284775
"
/>
</
asp:GridView
>
</
div
>
</
form
>
</
body
>
</
html
>