treeview_shimpark.zip


출처 : 고수닷넷/GosuWeb/Article-detail.aspx?ArticleCode=1250

이번에는 새로 vs 2005 에서 제공하는 트리에 대해서 설명을 하고자 합니다.

 

다들 아시겠지만, 새로 접근하시는 분들을 위해서 강좌를 올리고자 합니다.

 

기존의 1.1 에는 treeview 컨트롤을 제공하지 않아서 유로 컴포넌트를 사던가 아니면

 

기존 vs.net 2003 에서 제공하지 않았지만, 비스무리한 treeview 를 제공한 iewebcontrol 이라는

 

것을 제공했습니다. 하지만 다루기가 만만치 않고, 까다롭고 많은 기능이 없어서 사용하기가

 

너무 어렵더군요.

 

따라서 서버 컨트롤인 treeview 가 vs 2005에서 제공해 주어서 편리하게 다루게 되었습니다.

 

우선 aspx 단에 아래와 같이 코딩을 합니다.

 

 

 

 

 <asp:TreeView ID="TreeView1" runat="server" OnTreeNodePopulate="TreeView1_TreeNodePopulate" ShowLines="True"
            >
            <Nodes>
                <asp:TreeNode Text="Customers" Value="Customers" PopulateOnDemand="True" Expanded="False"></asp:TreeNode>
            </Nodes>
        </asp:TreeView>

 

트리뷰를 aspx 디자인 페이지에 끌어다 두어서 위와 같이 편집을 하면 됩니다.

여기서 OnTreeNodePopulate 메소드는 TreeView 컨트롤의 TreeNodePopulate 이벤트를 발생시킵니다.  그러면 TreeNodePopulate 메소드가 하는 역할이 뭘까요?

"TreeView 컨트롤에서 PopulateOnDemand 속성이 true로 설정된 노드를 확장할 때 발생합니다. "

라도 설명이 되어 있더군요.  PopulateOnDemand 를 true 로 설정하면 트리의 노드를 확장시킬수

있고, 이벤트 시킬수 있다는 의미랍니다.

 

그래서  <asp:TreeNode Text="Customers" Value="Customers" PopulateOnDemand="True" Expanded="False"></asp:TreeNode> 의 소스를 보면 PopulateOnDemand 의 속성값을 true 로

주었습니다. 따라서 비하인드에 기술된 protected void TreeView1_TreeNodePopulate(object sender, TreeNodeEventArgs e) 메소드를 노드 클릭시 이벤트가 발생된다는 의미지요.

 

ShowLines 메소드는 트리 보여줄때 선을 보여줄지를 의미합니다. 보여주면 뽀대가..좀 나겠죠? ㅋㅋ

 

그리고 처음 tree를 페이지에 뜰경우 Text="Customers" Value="Customers" 을 지정해서 최상위

트리에 Customers 라는 트리노드의 글자가 나타나도록 해둡니다. 아무것도 안뜨면 트리의 어디

부분을 클릭해서 하위노드를 펼쳐줄 수 없잖아요.. ^^

흠..그리고 Expanded 가 false 라고 되어 있죠? 이 부분은 노드가 확장 상태인지 여부를 나타내는 값을 가져오거나 설정합니다. 따라서 지금은 최상위 노드만 보여주고 하위노드는 클릭시 나타나도록

하기 위해서  false 로 했습니다.

 

그려면..한번 로딩해볼까요? 비하인드는 아무것도 기술하지 않고요.

 



그러면 이제 저...노드를 클릭하면 이벤트를 발행시켜서 하위 노드를 추가해서 뽀대나는 트리를

구현해 보죠.

 

노드를 선택할 경우 이벤트를 발생하는 메소드를 구현해보죠.

 

protected void TreeView1_TreeNodePopulate(object sender, TreeNodeEventArgs e)
    {
        switch (e.Node.Depth)
        {
            case 0:
                FillCustomers(e.Node);
                break;
            case 1:
                FillOrders(e.Node);
                break;
        }
    }

 

depth 는 말그대로 깊이라는 의미인데요. 최상위 노드는 0 이고 그 밑의 자식은 1이 되겠죠?

1의 자식은 2가 되는거고요.

 

처음 노드를 클릭할 경우 0일 테고 FillCustomers(e.Node) 메소드를 실행하러 가겠죠?

 

private void FillCustomers(TreeNode parent)
    {
        DataSet ds = GetDataSet("select customerid,companyname from customers order by companyname");
        foreach (DataRow row in ds.Tables[0].Rows)
        {
            TreeNode node = new TreeNode();
            node.Text = row["companyname"].ToString();
            node.Value = row["customerid"].ToString();
            node.PopulateOnDemand = true;
            node.SelectAction = TreeNodeSelectAction.SelectExpand;
            parent.ChildNodes.Add(node);
        }
    }

 

 

GetDataSet 메소드는 실행할 경우 쿼리를 실행한 DataSet 값을 리턴해 줄것이고요. 그 DataSet

값을 받아 foreach 문을 실행해서 각각의 노드에 Text, Value , PopulateOnDemand 메소드 값 설정,

노드가 선택 모드에 있는 경우 노드가 선택될 때 발생하는 이벤트를 지정하려면 SelectAction 속성을 사용합니다. 그 속성에 TreeNodeSelectAction.SelectExpand 를 지정했는데요.

노드가 선택될 때 SelectedNodeChanged 이벤트와 TreeNodeExpanded 이벤트를 모두 발생시킬수 있답니다. 노드는 확장할 수만 있고 축소할 수는 없는 기능입니다.

이 기능뿐만 아니라 아래와 같은 기능들이 총 3가지 더 있습니다.

msdn 이 설치 되어 있다면 ms-help://MS.VSCC.v80/MS.MSDN.v80/MS.NETDEVFX.v20.ko/cpref16/html/P_System_Web_UI_WebControls_TreeNode_SelectAction.htm을 확인해 보시기 바랍니다.

 

 

하위 노드를 추가할 경우, parent.ChildNodes.Add(node); 을 사용하고 있는것을 살펴보고 있어요.

부모.자식.Add(node특성값) 이라는 구조를 가지고 있죠. ChildNodes 메소드를 추가해서 하위노드를

추가하는 모습을 볼 수 있죠.

 

 

이제 실행을 해볼까요?

 

 



위처럼 최상위 노드의 자식인 1depth 에 위 그림 처럼 출력이 됩니다.

 

그러면 저 1depth 의 많은 자식들 중에도 그 아래의 하위 자식들이 각각 있겠죠?

그러면 sql 쿼리의 where 조건에 선택한 노드의 값을 넣어서 그 밑의 자식값을 추출해와서

2depth 의 하위조직을 만들 수 있겠죠.

 

 case 1:
                FillOrders(e.Node);
                break;

 

위에서 보셨던 이벤트에서 기술한 소스 입니다.  이제 FillOrders 를 볼까요?

 

 

private void FillOrders(TreeNode parent)
    {
        DataSet ds = GetDataSet("select customerid,orderid from orders where customerid='" + parent.Value + "'");
        foreach (DataRow row in ds.Tables[0].Rows)
        {
            TreeNode node = new TreeNode();
            node.Text = row["orderid"].ToString();
            node.Value = row["orderid"].ToString();
            node.PopulateOnDemand = false;
            node.SelectAction = TreeNodeSelectAction.SelectExpand;
            parent.ChildNodes.Add(node);
        }
    }

 

거의 동일하죠??? 다른 점은 where 조건문을 보시면 알게 될겁니다.

선택한 노트의 값을 얻고자 한다면 parent.Value 을 사용하시면 값을 얻을 수 있습니다.

그 밑에 기술한 속성은 이미 위에서 미리 설명해서 여기서는 말씀드리지 않겠습니다.

 

 

어떠세요? 쉽게 제가 설명을 했는지 모르겠네요. 간단한 기능만 제가 설명을 해드렸는데요.

이 트리는 노드를 한번 선택했을 경우 sql 에서 값을 받아 노드를 셋팅하고, 다시 그 노드를

접거나 펼칠경우 이벤트를 다시 타서 sql 문을 실행하지 않으므로 속도면을 걱정할 필요는

없을 듯 합니다.

 

 

 

첨부해 드리니 테스트 해보시기 바랍니다.

감사합니다.

 

 

 

=======================================

사이트 : http://cafe.daum.net/aspdotnet

작성자 : 심재운

메일 : shimpark@gmail.com

=======================================



Posted by 뭉치냐옹
:

Set  - form 태그의 runat="server" 제거

<form id="form1" action="Default2.aspx" method=post>
    <div>
        Default.aspx<br />
        <br />
        <input id="txtName" type="text" name="txtName" />
        <input id="Pwd" type="text" name="Pwd"/><br />
        <input type=hidden id=txtTest name=txtTest value="000" />
        <input id="btnSend" type=submit value="button"/></div>
    </form>

 

 

Get - 코드비하인드에서 받음

    protected void Page_Load(object sender, EventArgs e)
    {
        string strName = Request.Form["txtName"].ToString();
        string strTest = Request.Form["txtTest"].ToString();
        string Name = Request.Form["Pwd"];
    }


Posted by 뭉치냐옹
:

[사용자 정의 컨트롤이 부모 aspx 변수 값 접근 하는 방법]

 

부모 페이지에 public 변수를 선언하고...

예) 부모.aspx - public string index;

 

그러면 자식 컨트롤(ascx)에서 다음과 같이 참조..

예) 자식.ascx - ((부모페이지 클래스)Context.Handler).index


Posted by 뭉치냐옹
:

.aspx

<script language="javascript">
  // 지분투자 회사 삭제
  function Delete(companyID)
  {
   document.all.hidDelCompanyID.value = companyID ;
   
   if(!SrcConfirmDialog("623", "264px", "136px"))
    return false;
   else
    __doPostBack('btnDel','') ;
  }
  </script>

 

 

Common.js

/*
 1. 메서드내용 : 팝업창 띄우기 --> 팝업창으로 어떤 문제에 대해서 확인을 받아야하는 경우 사용
 2. 매개변수
  (1) iMsgCode : 컨펌창에 표시될 문장코드
  (2) obj   : Parent 오브젝트를 나타냄
  (3) widthPX  : 팝업창 가로 길이
  (4) heightPX : 팝업창 세로길이
  (5) scrollOX : 팝업창의 스크롤 여부 (디폴트 : auto)
  (6) popTitle : 팝업창의 제목표시줄에 표시될 제목 (디폴트 : iPopup)
 3. 반환값  : 팝업창의 리턴값
*/
function SrcConfirmDialog(messageInfo, widthPX, heightPX)
{
 return ConfirmSrcPopupDialog('../WCommon/PopupConfirm.aspx?messageInfo='+messageInfo, window, widthPX, heightPX, 'no', '확인메시지' )
}

 

 

function ConfirmSrcPopupDialog()
{
 var passURL, obj, widthPX, heightPX, scrollOX, popTitle, SrcPopupArgs = ConfirmSrcPopupDialog.arguments;
 
 passURL  = SrcPopupArgs[0]; // 팝업창에 보여줄 화면 Url
 obj   = SrcPopupArgs[1];  // 팝업창을 띄우는 parent object
 widthPX  = SrcPopupArgs[2];  // 팝업창의 가로길이
 heightPX = SrcPopupArgs[3];  // 팝업창의 세로길이
 scrollOX = (SrcPopupArgs[4]== null ? 'auto' : SrcPopupArgs[4]) ;  // 팝업창의 스크롤여부
 popTitle = (SrcPopupArgs[5]== null? 'iPopup' : SrcPopupArgs[5]) ; // 팝업창의 제목표시줄에 표시될 제목
 var srcURL = "../WCommon/iConfirmPopupMng.aspx?passURL="+escape(passURL)+'&scrollOX='+scrollOX +'&popTitle='+popTitle+'&height='+heightPX;
    var res  = window.showModalDialog(srcURL, obj, "dialogHeight:"+heightPX+"px; dialogWidth:"+widthPX+"px; help:no; status:no; scroll:no ; unadorned:no;");
    return res;

Posted by 뭉치냐옹
:
ASP.NET or .NET 초보자 FAQ
[한빛미디어] 2002-03-04 14:57  
저자: 한동훈(lorikeet@unitel.co.kr)

.NET Framework가 나오고, C#이 세상에 나온 것이 2000년도였고, 베타1에서 ASP.NET 응용 프로그램을 작성하면서 새로운 기능들을 조금씩 익혀나갔던 기억이 난다. 지금은 벌써 2002년이고, .NET Framework 정식버전이 나왔고, VS.NET도 출시가 되었다. 그럼에도 불구하고 여전히 많은 것들이 정리가 되지 않은 듯하고, 비슷한 시행착오를 겪고 있으며 많은 닷넷 관련서적들이 출간이후 절판되었고, 개발자마다 모두 사용하는 방법이 다르다.

그중에 가장 자주 질문하는 몇가지만 알아보자. 여기서는 .NET Framework v 1과 VS.NET 정식버전을 기준으로 설명한다.

Q. .NET Framework v 1 또는 VS.NET을 설치한 이후에 ASP.NET을 실행하면 'Server Application Unavailable'이라고 나타나면서 실행되지 않습니다.

A. ASP.NET은 ASPNET이라는 계정으로 실행되며, 이 계정은 아주 제한된 권한만을 갖고 있습니다. 베타2까지는 ASP.NET은 SYSTEM 계정으로 실행되었습니다. SYSTEM 계정은 관리자 권한을 갖고 있기 때문에 보안상 문제가 될 수 있기 때문에 정식버전에서부터는 SYSTEM 계정을 사용하지 않습니다. 그러나 도메인 컨트롤러로 사용중인 윈도우 2000 서버에서 ASP.NET을 실행하려면 SYSTEM 권한이 필요합니다.

C:\WINNT\Microsoft.NET\Framework\v1.0.3705\CONFIG\machine.config 파일에서 <processModel> 태그를 찾아서 userName="SYSTEM" 으로 변경해야합니다. 최초 설치시에는 userName=machine으로 설정되어 있습니다. 이것은 worker thread로 동작하는 것이도 대부분의 ASP.NET 응용 프로그램에는 적합합니다.

<processModel userName="SYSTEM"…>
이와 같이 변경하면 문제없이 실행할 수 있습니다. 이 증상은 도메인 컨트롤러에서 ASP.NET을 실행할때만 나타납니다.

만약 윈도우 닷넷 서버를 사용하고 있다면 ASPNET 사용자 계정을 사용하는 경우에 IIS 5는 Isolation(격리) 모드에서만 동작합니다. 이 경우에는 NetworkService로 이용하는 것이며, application pool level에서 사용하는 것을 뜻합니다.

Q. 마우스를 버튼에 위치시키거나 링크를 위치시킬 때 색상을 변경하려면 어떻게 합니까?

A. 웹 폼에 버튼을 하나 두고, 이름은 Button1이라고 하면 다음과 같은 코드를 Page_Load 메소드에 추가하면 됩니다.

private void Page_Load(object sender, System.EventArgs e)
{
  if ( !Page.IsPostBack )
  {
    Button1.Attributes.Add("onmouseover", "this.style.backgroundColor='lightyellow';");
    Button1.Attributes.Add("onmouseout", "this.style.backgroundColor='white';");
  }
}
if 문장에서와 같이 페이지를 처음 로드하는 경우인지를 확인해야한다. 그렇지 않으면 폼이 갱신될때마다 브라우저에서 동작하는데는 문제가 없지만 동일한 이벤트에 대해서 자바스크립트가 계속해서 중복되어 생성되는 현상이 나타난다.

Q. 텍스트 박스에 포커스가 있을 때 배경색을 변경하고 싶습니다.

A. 마우스 이벤트를 이용하는 코드와 같다. 위 코드에서 onmouseover 대신에 onfocus를 사용하고 onmouseout 대신에 onfocusout을 사용하면 된다. onfocus는 텍스트 박스에 포커스가 이동할 때 발생하는 이벤트를 정의한다. onfocusout은 텍스트 박스가 포커스를 잃을 때 발생한다. 이들은 모두 클라이언트 스크립트로 동작하기 때문에 서버와 데이터를 주고 받지않고 동작한다.

Q. 삭제 버튼을 클릭하면 대화창을 띄워서 확인하고 싶습니다.

A. 게시판의 삭제나 레코드의 삭제를 실행하기전에 확인창을 띄우는 것은 좋은 프로그래밍 습관이다. 이와 같이 하려면 Button1 버튼에 대해서 다음과 같은 코드를 Page_Load 이벤트에 추가한다.

Button1.Attributes.Add("onclick", "return confirm('Delete?');");
Q. 기존에 SQL 서버에 연결할 때는
SqlConnection myConnection = new SqlConnection("server=localhost;database=pubs;uid=sa;pwd=;");
과 같이 사용했는데
SqlConnection DbCon = new SqlConnection("Initial Catalog=Northwind;
                      Data Source=localhost;Integrated Security=SSPI;");
와 같이 사용하는 것을 보았습니다. VS.NET에서부터 바뀐것인가요?


A. 그렇지 않습니다. 이것은 ADO에서부터 사용되던 방법입니다. 최근에 닷넷에서 프로그래밍을 하는 경우에 Integrated Security와 같은 연결 문자열을 사용하는 것을 많이 볼 수 있기는 하지만, 전혀 새로운 것은 아닙니다. 다만, Integrated Security등의 사용은 스테이지 서버에서 프로덕션 서버로 패키지를 옮기거나 다양한 환경에서 보안설정상의 실수로 인해서 제대로 동작하지 않을 수 있고, 다양한 보안환경에 적용하기에는 무리가 있으므로 크게 사용하는 것을 권하지는 않습니다. uid와 pwd를 사용하는 것을 MSDN에서는 권하고 있습니다.

ADO에서는 Integrated Security를 다음과 같이 사용할 수 있습니다.

Dim dc As New ADODB.Connection
'저는 Data Connection의 의미로 dc라는 약어를 즐겨 사용합니다  
dc = "Provider=MSOLAP; SSPI=Negotiate; Prompt=1"  
dc.Open
SSPI는 인증된 연결(Authenticated Connection)을 통해서 데이터를 교환하기 위한 인터페이스이기 때문에 SSPI는 해당 프로바이더에서 지원할 수도 있고, 하지 않을 수도 있습니다.

SSPI는 Security Support Provider Interface의 약자입니다. MSOLAP는 MS OLAP 서비스에서 제공하는 프로바이더이며, 여기서 사용할 수 있는 인증에는 NTLM, Kerberos, Negotiate, Anonymous User가 있습니다.

Q. 닷넷은 XML 기반이라기에 XML, XSL을 공부중에 잘못된 부분이 있으면 깨진글자로 에러를 알려주는데 해결할 방법은 무엇인가요? encoding에 EUC_KR, ISO8859_1 같은 걸 넣었더니 그런 인코딩은 지원하지 않는다고 합니다.

A. encoding="euc-kr"로 하시면 됩니다. XML 관련 툴이나 파서에 대한 것은 http://www.garshol.priv.no/download/xmltools/에서 확인할 수 있습니다.

Q. 데이터 구조나 알고리즘에 대해서 C#으로 된 것이 있습니까?

A. Bruno R. Preiss의 홈페이지로 가세요. 이곳에 Java, C#, C++ 버전으로 된 각각의 문서가 있습니다.

이곳에는 Data Structures and Algorithms with Object-Oriented Design Patterns 온라인 도서를 세 가지 언어별로 볼 수 있습니다.

또한 자바와 C#의 VM, CLR에서 가비지 컬렉션에 사용하고 있는 알고리즘의 하나인 Mark & Sweep Garbage Collector에 대해서 설명하고 있으니, 가비지 컬렉션이나 닷넷에서의 자원 관리가 궁금한 분들은 참고하시기 바랍니다.

http://labsoftware.com/labsoftware/CSharpPats/design_patterns_in_c.htm 이곳에는 C# 버전으로 된 Design Patterns를 받아볼 수 있습니다. 이 책은 Design Patterns의 저자가 C# 버전으로 작성한 것입니다.

Q. 데이터그리드에서 게시판에 번호등을 표시하고 싶습니다. 어떻게 하면 될까요?

A. ASP.NET에서 게시판과 같이 번호를 매기고, 목록을 보여주는 방법은 다양합니다. 기존의 ASP에서 하던 것과 같은 방법에서부터 ASP.NET의 새로운 클래스들을 이용하는 방법까지 있습니다. 여기서는 그중의 하나인 DataRow를 이용해서 각각의 컬럼을 커스터마이징하는 방법에 대해서 설명합니다. 데이터그리드를 커스터마이징하려면 데이터그리드의 AutoGenerateColumns 속성을 False로 변경합니다.

ICollection CreateDataSource()
    {
      DataTable dt = new DataTable();
      DataRow dr;

      dt.Columns.Add(new DataColumn("Number", typeof(int)));
      dt.Columns.Add(new DataColumn("Name", typeof(string)));
      dt.Columns.Add(new DataColumn("Title", typeof(string)));
      dt.Columns.Add(new DataColumn("WriteTime", typeof(System.DateTime)));

      string query = "SELECT Name, Title WriteTime FROM Info ORDER BY ID DESC";
      string connectionString = "server=(local); database=BBSTable; uid=sa; pwd=;"
      SqlDataAdapter da = new SqlDataAdapter(query, connectionString);

      DataSet ds = new DataSet();
      da.Fill(ds, "AuthorInfo");
      DataTable dtList = new DataTable();
      dtList = ds.Tables["AuthorInfo"];

      int loopctr = dtList.Rows.Count;

      foreach( DataRow row in dtList.Rows)
      {
          dr = dt.NewRow();
          dr[0] = loopctr;
          dr[1] = row["Name"];
          dr[2] = CreateTitleLink(row["Title"].ToString());
          dr[3] = Convert.ToDateTime(row["WriteTime"]).ToString();

          dt.Rows.Add(dr);
          loopctr--;
      }

      DataView dv = new DataView(dt);

      return dv;
    }  // end of CreateDataSource();
처음에 DataTable을 생성하고 테이블에 사용할 컬럼을 추가하기위해 DataTable.Columns.Add를 사용합니다. loopctr은 DataTable.Rows.Count 값을 저장하고 목록에 보여줄 때는 1씩 증감하면서 출력합니다. 이렇게 하면 일반 게시판 목록을 만들 수 있습니다.

각각의 foreach 루프에 대해서 DataRow = DataTable.NewRow()를 사용하여 동적으로 새로운 열을 추가하고 질의를 통해 가져온 값은 DataRow["FieldName"]으로 직접 가져올 수 있습니다. 게시판의 제목부분에 링크를 위한 태그와 같은 별도의 처리가 필요하다면 직접 코드를 넣는 대신에 public void CreateTitleLink(string sTitle)과 같은 함수에서 처리하도록 하고, 여기서는 함수를 이용합니다. 표시할 열을 모두 만들었으면 DataView를 생성합니다. DataView는 가상의 레코드집합으로 일종의 필터와 같은 역할을 합니다.

중요한 것은 이 함수는 ICollection이 반환값으로 되어 있습니다. 즉, ICollection 인터페이스를 구현한 클래스에서 이 함수의 반환값을 모두 사용할 수 있다는 것을 뜻합니다.

웹폼에 있는 ASP.NET 데이터그리드의 이름이 myDataGrid라고 한다면 Page_Load에 다음과 같이 사용하면 됩니다.

myDataGrid.DataSource = CreateDataSource();
myDataGrid.DataBind();
데이터그리드역시 ICollection 인터페이스를 구현하고 있습니다. 이렇게 커스터마이징한 데이터를 데이터그리드에 표시하려면 데이터그리드도 수정해야합니다. 다음은 데이터그리드부분만을 가져온 것입니다.

<asp:datagrid id="myDataGrid" runat="server" Width="800px" PageSize="10" PagerStyle-
HorizontalAlign="Right" PagerStyle-NextPageText="Next" PagerStyle-PrevPageText="Prev" Font-
Name="굴림체" AllowPaging="True" AutoGenerateColumns="False">
          <EditItemStyle HorizontalAlign="Center" Height="25px" 
VerticalAlign="Middle"></EditItemStyle>
          <AlternatingItemStyle Font-Size="X-Small" HorizontalAlign="Center" 
VerticalAlign="Middle" BackColor="AliceBlue"></AlternatingItemStyle>
          <ItemStyle Font-Size="X-Small" HorizontalAlign="Center" Height="25px" 
VerticalAlign="Middle"></ItemStyle>
          <HeaderStyle Font-Size="X-Small" Font-Bold="True" HorizontalAlign="Center" 
Height="25px" VerticalAlign="Middle" BackColor="Gainsboro"></HeaderStyle>
          <Columns>
            <asp:BoundColumn DataField="Number" HeaderText="번호"></asp:BoundColumn>
            <asp:BoundColumn DataField="Name" HeaderText="이름"></asp:BoundColumn>
            <asp:BoundColumn DataField="Title" HeaderText="제목"></asp:BoundColumn>
            <asp:BoundColumn DataField="WriteTime" HeaderText="등록일"></asp:BoundColumn>
          </Columns>
</asp:datagrid>
컬럼을 정의하기 위해 <asp:BoundColumn>을 사용합니다. 또한 컬럼에 대해서 필드명 대신에 제목을 표시하기 위해 HeaderText를 사용합니다. 주의할 것은 dt.Columns.Add(new DataColumn("Number", typeof(int)));에서 사용한 컬럼명 "Number"가 <asp:BoundColumn>의 DataField에 있는 값과 일치해야합니다. 이제 이것으로 데이터그리드를 커스터마이징 할 수 있었습니다.

ASP에서 처럼 데이터를 직접 질의하고 처리할것이라면 DataReader를 사용하는 것이 더 좋으며, ASP.NET에서 데이터그리드외에 Repeater를 사용하는 것도 좋습니다. 실제로 대부분의 ASP.NET 게시판은 DataReader와 Repeater를 사용하여 구현되어 있습니다.

Q. ASP.NET에서 데이터그리드를 사용하여 페이징을 구현하고 싶습니다.

A. 데이터그리드의 이벤트에서 PageIndexChanged에 myDataGrid_Page를 입력합니다. 또는 직접 텍스트 편집기를 사용하여 다음과 같이 입력할 수 있습니다.

<asp:datagrid OnPageIndexChanged="myDataGrid_Page" … >
이것은 페이징에 대한 처리를 myDataGrid_Page에서 처리하라는 것을 뜻합니다. 이 함수는 다음과 같이 작성하면 됩니다.

public void myDataGrid_Page(object sender, DataGridPageChangedEventArgs e)
{
  int startindex;
  startindex = myDataGrid.CurrentPageIndex * myDataGrid.PageSize;
  myDataGrid.CurrentPageIndex = e.NewPageIndex;
  myDataGrid.DataSource = CreateDataSource();
  myDataGrid.DataBind();
}
한 페이지에 몇 개의 목록을 보여줄지를 결정하는 PageSize, 현재 페이지 번호를 알려주는 NewPageIndex 등은 DataGridPageChangedEventArgs에서 가져옵니다.

실제로 페이징을 처리하는 이벤트는 다음 함수에서 발생합니다.

public void PagerButtonClick(Object sender, EventArgs e) 
    {
      // Used by external paging UI.
      string arg = ((LinkButton)sender).CommandArgument;
      string SearchType = String.Empty;
      string SearchString = String.Empty;

      switch(arg)
      {
        case ("next"):
          if (myDataGrid.CurrentPageIndex < (myDataGrid.PageCount - 1))
            myDataGrid.CurrentPageIndex ++;
          break;
        case ("prev"):
          if (myDataGrid.CurrentPageIndex > 0)
            myDataGrid.CurrentPageIndex --;
          break;
        case ("last"):
          myDataGrid.CurrentPageIndex = (myDataGrid.PageCount - 1);
          break;
        default:

          // Page number.
          myDataGrid.CurrentPageIndex = Convert.ToInt32(arg);
          break;
      }

    }
다음은 데이터그리드입니다. 데이터그리에서는 PageSize="10"으로 되어 있습니다. 이것은 하나의 페이지에 10개의 레코드만을 보여주는 것을 뜻합니다. 페이징을 위해서 OnPageIndexChanged="myDataGrid_Page"로 되어 있는 것을 볼 수 있습니다. 또한 AllowPaging="True"로 설정했습니다.

<asp:datagrid id="myDataGrid" runat="server" Width="800px" PageSize="10" PageCount="1" 
PagerStyle-HorizontalAlign="Right" PagerStyle-NextPageText="Next" PagerStyle-
PrevPageText="Prev" OnPageIndexChanged="myDataGrid_Page" Font-Name="굴림체" AllowPaging="True" 
AutoGenerateColumns="False">
          <EditItemStyle HorizontalAlign="Center" Height="25px" 
VerticalAlign="Middle"></EditItemStyle>
          <AlternatingItemStyle Font-Size="X-Small" HorizontalAlign="Center" 
VerticalAlign="Middle" BackColor="AliceBlue"></AlternatingItemStyle>
          <ItemStyle Font-Size="X-Small" HorizontalAlign="Center" Height="25px" 
VerticalAlign="Middle"></ItemStyle>
          <HeaderStyle Font-Size="X-Small" Font-Bold="True" HorizontalAlign="Center" 
Height="25px" VerticalAlign="Middle" BackColor="Gainsboro"></HeaderStyle>
<Columns>
            <asp:BoundColumn DataField="Number" HeaderText="번호"></asp:BoundColumn>
            <asp:BoundColumn DataField="Name" HeaderText="이름"></asp:BoundColumn>
            <asp:BoundColumn DataField="Title" HeaderText="제목"></asp:BoundColumn>
            <asp:BoundColumn DataField="WriteTime" HeaderText="등록일"></asp:BoundColumn>
          <PagerStyle VerticalAlign="Middle" NextPageText="다음" Height="25px" 
BorderWidth="0px" Font-Size="X-Small" PrevPageText="이전" BorderStyle="None" 
HorizontalAlign="Right"></PagerStyle>
        </asp:datagrid>
이와 같이 하면 데이터그리드를 이용하여 페이징을 손쉽게 구현할 수 있습니다.

Q. 입력, 수정, 조회, 검색을 하나로 하고 싶습니다. 어떻게 할까요?

A. 입력, 수정, 조회, 검색등은 화면에 표시되는 정보에 있어서 약간의 차이가 있을 뿐, 대개의 경우에 나머지는 동일합니다. 이러한 경우에 하나의 폼을 웹 컨트롤로 작성하고 이것을 컨트롤로 이용하는 방법이 있습니다. 조회 화면에서는 TextBox1.ReadOnly = True로 하고, 수정화면에서는 TextBox1.ReadOnly=False로 하여 수정할 수 있습니다.

또는 모든 텍스트박스의 AutoPostBack 속성을 True로 설정하고, 데이터를 변경하는 경우에 실시간으로 업데이트하도록 할 수도 있습니다.

추천하는 방법은 웹 컨트롤로 작성하고, 각각의 화면에 따라서 적절하게 컨트롤의 ReadOnly 속성을 설정하거나, Visible 속성을 이용해서 화면에서 안보이도록 하는 것입니다.

Q. 데이터베이스에 입력하고 조회를 하니 모든 데이터가 한 줄로 나타납니다. 어떻게 하면 줄 바꿈을 할 수 있을까요?

A. 줄 바꿈을 위해서는 엔터키에 해당하는 아스키(ASCII) 코드 13번 값을 HTML에서 사용하는 <br> 태그로 변환해야합니다. 이와 같이 하려면 다음과 같은 코드를 사용합니다.

string sResult = String.Empty;
StringBuilder sbText = new StringBuilder(TextBox1.Text);
sbText.Replace("\r\n", "<br>");
sResult = sbText.ToString();
반대로 수정화면에서 원래의 코드로 변환하려면 Replace 함수 부분만 다음과 같이 바꿔주면 됩니다.

sbText.Replace("<br>", "\r\n");
Q. 드롭다운리스트를 데이터베이스에 있는 값으로 동적으로 채우려면 어떻게 합니까?

A. DropDownList를 데이터베이스에서 동적으로 채우려면 다음과 같은 코드를 사용한다. 테이블에는 숫자필드인 ID, 문자열 필드인 Name이 있다고 가정한다.

public void FillDropDownList1()
    {
      string query = "SELECT ID, Name FROM Field";

      SqlConnection dc = new SqlConnection("server=(local); database=FieldDB; 
      uid=sa;pwd=;");
      dc.Open();

      SqlCommand myCommand = new SqlCommand(query, dc);
      SqlDataReader myReader = myCommand.ExecuteReader();

      int idxID = myReader.GetOrdinal("ID");
      int idxName = myReader.GetOrdinal("Name");

      while ( myReader.Read() )
      {
        DropDownList1.Items.Add(new ListItem(myReader.GetValue(idxName).ToString(), 
        myReader.GetValue(idxID).ToString()) );
      }

      myReader.Close();
      dc.Close();

    }
여기서는 간단히 하기위해 DataReader를 사용하여 테이블을 채우고 있다. DataReader.GetOrdinal("FieldName")은 레코드에서 현재 위치에 대한 참조를 설정하는 것이다. 각각의 루프를 돌면서 위와 같이 테이블을 채울 수 있다.

Q. CSV 형식을 읽어들이려면 어떻게 해야합니까?

A. CSV 형식은 ','로 각 필드가 구분된 형식을 뜻한다. 이 경우에는 다음과 같은 코드를 사용한다.

string sSource = "Hello,World, 4";
string [] arrStr = {};

arrStr = sSource.Split( new Char[] {','} );

foreach( string str in arrStr )
{
  Console.WriteLine(str.ToString());
}
이와 같이 하면 Hello,World, 4를 각각의 토큰으로 분리한다는 것을 알 수 있을 것이다. 여백은 구분하지 않는다.

Q. ASP.NET 디버깅 정보가 나타나지 않습니다. 또는 어떤 것은 디버깅 정보가 나타나고 어떤 것은 디버깅 정보가 나타나지 않습니다. 어떻게 된 일이죠?

A. <%@ Page language="c#" Debug="True"%>와 같이 설정하면 됩니다. 또는 web.config 파일에 다음과 같이 입력합니다.

<compilation 
         defaultLanguage="c#"
         debug="true"
    />
일부 시스템에서 이러한 문제가 나타나지만 저역시 왜 이러한 문제가 나타나는지 정확하게 알지는 못합니다. 만약 사용자 계정에서 ASP.NET을 전혀 디버깅할 수 없다면 다음 항목들을 확인하도록 합니다. 사용자 계정이 ASP.NET 디버깅을 비롯해서 디버거를 사용하여 사용자가 생성된 프로세스에 대해서 디버깅할 수 있도록 하려면 관리자 권한이 필요합니다. 이를 위해서 .NET Framework를 설치하면 Debugger Users 그룹이 생성됩니다. 사용자를 이 그룹에 추가합니다. ASP.NET을 실행하는 동안에 생성되는 임시 파일이나 어셈블리 바인딩 로그등은 모두 C:\WINNT\Microsoft.NET\Framework\v1.0.3705\Temporary ASP.NET Files에 있습니다. 따라서 탐색기등을 이용하여 이곳에 해당 계정에 대한 사용권한이 있는지 확인합니다. 도메인 컨트롤러에서는 SYSTEM 계정을 사용하기 때문에 SYSTEM 계정은 이 폴더에 대해서 모든 권한을 갖고 있어야합니다. 마찬가지로 도메인 컨트롤러가 아닌 시스템에서도 문제가 생긴다면 ASPNET과 같은 계정에 이 폴더에 대한 권한을 부여해야합니다.

Q. 작성한 ASP.NET 응용 프로그램을 다른 웹 서버로 옮기려고 하는데 어떻게 해야합니까?

A. 작성한 ASP.NET 응용 프로그램이 있는 가상 디렉터리를 압축해서 다른 웹 서버로 옮기고, 해당 디렉터리에 대해서 가상 디렉터리로 설정해야합니다. 새로운 서버로 옮긴 다음에 VS.NET등에서 읽기 위치를 해당 ASP.NET 응용 프로그램의 URL로 지정하면 됩니다.

VS.NET에서는 기본 설정이 파일 공유(File Share) 모드입니다. VS.NET Solution Explorer에서 마우스 오른쪽 버튼을 클릭한 다음에 Project Property Pages | Common Properties | Web Settings를 선택하면 Web Server Connection 밑에 Web Access Mode를 변경할 수 있습니다. 이것을 FrontPage로 설정하면 Visual InterDev에서처럼 FrontPage 모드로 액세스할 수 있습니다. FrontPage 모드로 설정한 경우에 다른 웹 서버에 있는 프로젝트를 불러들이기가 편합니다.

이 보다 편한 방법은 VS.NET의 Solution Explorer에서는 다른 위치에 있는 각각의 Solution을 읽어들일 수 있습니다. 따라서 스테이지 서버의 솔루션과 프로덕션 서버의 솔루션을 모두 열어둔 다음에 Solution Explorer에서 스테이지 서버에서 복사할 파일들을 선택해서 프로덕션 서버 솔루션에 드랙앤 드롭만 하셔도 됩니다.(실제로 가장 간편합니다)

Q. ASP.NET 세션 기간을 늘리려면 어떻게 합니까?

A. VS.NET에서 global.aspx를 선택한 다음에 마우스 오른쪽 버튼을 클릭해서 Code View를 선택한 다음에 protected void Session_Start(Object sender, EventArgs e)에 다음과 같이 작성합니다.

Session.TimeOut = 60;
세션을 60분동안 유지하도록 설정하는 것이며 ASP와 같습니다. 이것은 HttpSessionState.TimeOut을 이용합니다. web.config 파일에서도 설정할 수 있으며 web.config의 설정 형식은 다음과 같습니다.

<sessionState 
            mode="InProc"
            cookieless="false" 
            timeout="20" 
    />
Q. 연결 문자열을 web.config 파일에 두고 이용할 수 있다고 하는데 어떻게 하는지요?

A. web.config에 파일의 경로나 데이터베이스 연결 문자열등을 다음과 같이 저장합니다.

<appSettings>
    <add key="ConnectionString" value="server=(local); database=BS_TABLE; uid=sa; pwd=;" />
<add key="FileLocation" value="ftp://localhost/public/" />
  </appSettings>
코드에서 이 값을 가져오려면 다음과 같이 합니다.

string connectionString = 
System.Configuration.ConfigurationSettings.AppSettings["connectionString"];
string fileLocation = System.Configuration.ConfigurationSettings.AppSettings["FileLocation"];
Q. 기존에 작성한 COM DLL을 ASP.NET에서 이용하거나 C#으로 작성한 DLL을 ASP에서 이용할 수 있습니까?

A. COM DLL을 ASP.NET에서 이용하려면 먼저 어셈블리로 변환해야합니다. 변환하려면 tlbimp.exe를 사용합니다. 이 프로그램의 위치는 VS.NET을 설치한 경우에 c:\program files\microsoft visual studio .net\FrameworkSDK\bin 입니다. 반대로 C#에서 작성한 DLL을 ASP에서 이용하려면 어셈블리를 COM DLL로 변환하는 것입니다. 이 경우에는 tlbexp.exe를 사용합니다. 사용법은 다음과 같습니다.

tlbimp.exe myCOM.DLL /out:myCOM2.DLL
이와 같이하면 COM으로 작성된 myCOM.DLL을 myCOM2.DLL 어셈블리로 변환합니다.

Q. ASP.NET에서 데이터베이스를 이용하여 프로그래밍을 하는데 한글이 깨집니다.

A. ASP.NET에서 web.config 파일에서 기본 값은 다음과 같습니다.

<globalization 
            requestEncoding="utf-8" 
            responseEncoding="utf-8" 
   />
일반적으로 영문 버전이나 한글 버전에 관계없이 한글이 깨지는 일은 없습니다. 데이터베이스에서 유니코드를 사용하도록 했다면 큰 문제는 없습니다. 만약에 한글이 깨진다면 utf-8 대신에 ks_c_5601-1987을 사용하도록 합니다.

Q. 파일을 업로드하는데 용량이 큰 파일은 업로드가 되지 않습니다.

A. 용량이 큰 파일을 업로드하는 경우에 처리 시간이 길어지기 때문에 timeout 되는 경우가 발생합니다. 또한 ASP.NET에서는 최대 요청 길이인 maxRequestLength를 설정할 수 있다. 이 설정은 web.config에서 할 수 있으며 다음과 같이 합니다.

<system.web>
<httpRuntime 
executionTimeout="600" 
maxRequestLength="20480" 
useFullyQualifiedRedirectUrl="false" />
</system.web>
이와 같이 설정하면 실행시간은 600초로 설정하고, 최대 전송 크기는 20M로 설정할 수 있습니다.
 

Posted by 뭉치냐옹
:
Posted by 뭉치냐옹
:

사용자정의 컨트롤.cs -> base.cs -> Presentation.cs


Posted by 뭉치냐옹
:

Page_Load에 써준다..

 

searchTXT.Attributes["onkeypress"] = " if( event.keyCode == 13 ){" + Page.GetPostBackEventReference(Button1) + "; return false;}";

 

브라우저 소스보기를 하면 다음의 결과가 나타난다..

<input name="searchTXT" type="text" id="searchTXT" onkeypress=" if( event.keyCode == 13 ){__doPostBack('Button1',''); return false;}" />

<input type="submit" name="Button1" value="검색" id="Button1" />


Posted by 뭉치냐옹
: