6. 기타 GridView에 관련되어서 알아둘 점.
1) GridView에 날짜 표현하기
데이터를 불러와서 GridView에 바인딩 시킬 때에는 기본적으로 필드가 DataTime 형식을 가지고 있을 경우에는 0000년 00월 00일 오전/오후 00:00:00 의 형식으로 웹 브라우저에서 보이게 됩니다. 이를 0000년 00월 00일 형식으로 보여주기 위해서 DataFormatString="{0:d}" 형식으로 많이 사용하는데 실제적으로 웹 화면에 보여지는 것은 이전과 동일하게 보여지게 됩니다.
그림 6-1. 날짜 형식이 변환되지 않은 GridView의 화면
이렇게 되는 이유는 MSDN에 다음과 같이 나와있습니다.(http://msdn2.microsoft.com/en-us/library/system.web.ui.webcontrols.boundfield.dataformatstring.aspx)
When the HtmlEncode property is true, the value of the field is HTML encoded to its string representation before the formatting string is applied. For some objects, such as dates, you might want to control how the object is displayed with a formatting string. In those cases, you must set the HtmlEncode property to false.
따라서, DataFormatString 속성을 사용할 경우에는 HtmlEncode 속성을 같이 사용하여야 합니다. HtmlEncode 속성을 false로 한 후에 다시 화면을 보면, 원하는 형식으로 바뀌어 있는 것을 확인할 수 있습니다.
그림 6-2. 날짜 형식이 변경된 GridView의 화면
2) RowDataBound 이벤트를 이용한 GridView의 확장
이전 포스트에서도 잠깐 언급한 바와 같이 GridView의 경우는 게시판 등의 리스트 화면을 꾸밀 때 상당히 유용합니다. 일반적으로 리스트 화면에서 리스트 위에 마우스 오버 및 마우스 아웃을 할 경우에 색이 변하는 것을 확인할 수 있습니다. 이것을 GridView에서도 사용할 수 있습니다.
코드는 다음과 같습니다.
<Default5.aspx.cs>
protected void GridView1_RowDataBound(object sender, GridViewRowEventArgs e)
{
DataRowView drView = (DataRowView)e.Row.DataItem;
if (e.Row.RowType == DataControlRowType.DataRow)
{
e.Row.Attributes.Add("onmouseover", "this.style.backgroundColor='#CCCCCC'");
e.Row.Attributes.Add("onmouseout", "this.style.backgroundColor='#FFF7E7'");
}
}
DataRowBound 이벤트를 이용하여 각각의 TR 태그에 onmouseover 속성과 onmouseout 속성에 배경색을 변경하도록 하는 속성을 추가하였습니다. 이를 웹 브라우저에서 실행해 보면 다음과 같이 mouseover 속성과 mouseout 속성이 적용되는 것을 확인할 수 있습니다.
그림 6-3. onmouseover 속성과 onmouseout 속성이 적용된 GridView
위에 사용한 GridView에 TemplateField 컨트롤을 2개 추가하고 각각이 TemplateField 컨트롤에 Label 컨트롤과 TextBox 컨트롤을 위치시키고 각 셀의 값을 화면에 출력해 보도록 하겠습니다. 소스는 다음과 같습니다.
<Default5.aspx>
<%@ Page Language="C#" AutoEventWireup="true" CodeFile="Default5.aspx.cs" Inherits="Default5" %>
<!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:SqlDataSource ID="SqlDataSource1" runat="server" ConnectionString="<%$ ConnectionStrings:AdventureWorksConnectionString %>" SelectCommand="SELECT Person.Address.* FROM Person.Address"></asp:SqlDataSource>
<asp:GridView ID="GridView1" runat="server" DataKeyNames="AddressID"
DataSourceID="SqlDataSource1" BackColor="#DEBA84" BorderColor="#DEBA84" BorderStyle="None" BorderWidth="1px" CellPadding="3" CellSpacing="2" AllowPaging="True" AllowSorting="True" PageSize="5" OnRowDataBound="GridView1_RowDataBound" AutoGenerateColumns="False">
<Columns>
<asp:BoundField DataField="AddressID" HeaderText="AddressID" InsertVisible="False" ReadOnly="True" SortExpression="AddressID" />
<asp:BoundField DataField="AddressLine1" HeaderText="AddressLine1" SortExpression="AddressLine1" />
<asp:BoundField DataField="AddressLine2" HeaderText="AddressLine2" SortExpression="AddressLine2" />
<asp:BoundField DataField="PostalCode" HeaderText="PostalCode" SortExpression="PostalCode" />
<asp:BoundField DataField="ModifiedDate" HeaderText="ModifiedDate" SortExpression="ModifiedDate" DataFormatString="{0:d}" HtmlEncode="False" />
<asp:TemplateField HeaderText="TemplateField1">
<ItemTemplate>
<asp:Label ID="lblTemp" runat="server" Text='<%#Eval("AddressID")%>'></asp:Label>
</ItemTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderText="TemplateField2">
<ItemTemplate>
<asp:TextBox ID="txtBox" runat="server" Text='<%#Eval("PostalCode")%>'></asp:TextBox>
</ItemTemplate>
</asp:TemplateField>
</Columns>
<FooterStyle BackColor="#F7DFB5" ForeColor="#8C4510" />
<RowStyle BackColor="#FFF7E7" ForeColor="#8C4510" />
<SelectedRowStyle BackColor="#738A9C" Font-Bold="True" ForeColor="White" />
<PagerStyle ForeColor="#8C4510" HorizontalAlign="Center" />
<HeaderStyle BackColor="#A55129" Font-Bold="True" ForeColor="White" />
</asp:GridView>
</div>
</form>
</body>
</html>
그리고, 코드 비하인드에서 첫 행에 대해서만 각 열의 값을 화면에 출력하도록 하였습니다. 다음은 코드 비하인드의 소스입니다.
<Default5.aspx.cs>
protected void GridView1_RowDataBound(object sender, GridViewRowEventArgs e)
{
DataRowView drView = (DataRowView)e.Row.DataItem;
if (e.Row.RowType == DataControlRowType.DataRow)
{
//e.Row.Attributes.Add("onmouseover", "this.style.backgroundColor='#CCCCCC'");
//e.Row.Attributes.Add("onmouseout", "this.style.backgroundColor='#FFF7E7'");
if (e.Row.RowIndex == 0)
{
for (int i = 0; i < e.Row.Cells.Count; i++)
{
Response.Write(String.Format("{0}번째 열 => {0}번째 열의 값은 {1}입니다. <br/>", i.ToString(), e.Row.Cells[i].Text));
}
}
}
}
화면에 출력하면 다음과 같이 열의 값들이 출력이 되게 됩니다.
그림 6-4. 각 열의 값을 출력한 화면
화면에서와 같이 0열부터 4열까지는 값이 제대로 출력이 된 것을 확인할 수 있으나, 5열과 6열은 값이 출력되지 않은 것을 볼 수 있습니다. 이것은 TemplateField를 적용한 열만 값이 출력이 되지 않는 것을 확인할 수 있으며, 이것은 TemplateField 컨트롤 안에 포함된 서버 컨트롤들은 TemplateField 컨트롤 안에 속한 컨트롤로 인식을 하기 때문에, 화면에 보이는 대로 값을 출력하기 위해서는 다음과 같이 각 열이 가지고 있는 Control을 찾아서 그 컨트롤의 값을 찾아야 합니다.
화면에 값을 정상적으로 출력하기 위해서 다음과 같이 코드 비하인드에 코드를 작성합니다.
<Default5.aspx.cs>
protected void GridView1_RowDataBound(object sender, GridViewRowEventArgs e)
{
DataRowView drView = (DataRowView)e.Row.DataItem;
if (e.Row.RowType == DataControlRowType.DataRow)
{
//e.Row.Attributes.Add("onmouseover", "this.style.backgroundColor='#CCCCCC'");
//e.Row.Attributes.Add("onmouseout", "this.style.backgroundColor='#FFF7E7'");
if (e.Row.RowIndex == 0)
{
for (int i = 0; i < e.Row.Cells.Count; i++)
{
if (i == 5)
{
Response.Write(String.Format("{0}번째 열 => {0}번째 열의 값은 {1}입니다. <br/>", i.ToString(), ((e.Row.Cells[i].Controls[1]) as Label).Text));
Label lblTemp = (e.Row.Cells[i].Controls[1]) as Label;
Response.Write(String.Format("{0}번째 열 => {0}번째 열의 값은 {1}입니다. <br/>", i.ToString(), lblTemp.Text));
}
else if (i == 6)
{
Response.Write(String.Format("{0}번째 열 => {0}번째 열의 값은 {1}입니다. <br/>", i.ToString(), ((e.Row.Cells[i].Controls[1]) as TextBox).Text));
TextBox txtTemp = (e.Row.Cells[i].Controls[1]) as TextBox;
Response.Write(String.Format("{0}번째 열 => {0}번째 열의 값은 {1}입니다. <br/>", i.ToString(), txtTemp.Text));
}
else
{
Response.Write(String.Format("{0}번째 열 => {0}번째 열의 값은 {1}입니다. <br/>", i.ToString(), e.Row.Cells[i].Text));
}
}
}
}
}
실행시켜 보면 정상적으로 화면에 구하고자 하는 값들이 출력된 것을 확인할 수 있습니다.

그림 6-5. 각 열의 값이 정상적으로 출력된 화면
5번째 열 및 6번째 열을 2번씩 출력하게 한 것은 코드에서 작성한 2가지 방식 중 어느것을 써도 같은 결과가 나온다는 것을 보여주기 위해서입니다. 위와 같은 코드로 TemplateField 컨트롤에 포함되어 있는 컨트롤의 값을 가져올 수 있습니다.
포스팅을 마치며... ----------------------------------------------------------------------------
이 외에도 여러가지 GridView에서 사용할 수 있는 기술(방법)들이 있으나, 이것은 나중에 작성될 포스트인 게시판 만들기에서 기술하고자 합니다. 위에 기술한 방법들은 알아두면 개발에 편리하게 사용될 기술들을 나열하였으니, 잘 숙지하시기 바랍니다.