통합검색
· 마을서비스란?  · 포럼마을  · 일반마을  · 테마마을  · 마을랭킹  · 활동왕
· 덱스퍼트란?  · TECBOX   · PRSBOX   · 이용안내  
· DEXT제품군  · 솔루션베이  · S/W & ESD 컴포넌트
· 프로그램베이
· LiveSeminar  · LiveConference
WPF & Silverlight 포럼마을입니다.
  마을등급 WPF & Silverlight   이 마을은 포럼마을 입니다이 마을은 자유가입제 마을 입니다 마을소개 페이지로 이동 전입신청
마을촌장촌장 서학수 주민 728 since 2008-07-17
우리마을 공지사항
질문&답변
강좌&팁
자유게시판
자료실
앨범
[마을 게시판]
WPF 강좌
랑데브 게시판
칼럼 게시판
개발자 고충상담
Dev Talk
자유토론방
벼룩시장
재나미 우스개
구인/프로젝트 정보
사람인 채용 게시판
  고객지원 게시판
마이 데브피아
 나의 e-Money 내역
 활동왕 My Page
 스크랩한 게시글보기
 쪽지관리
 주소록관리

 강좌&팁
 Form Designer 프로젝트 #2 - TreeView 구성  | WPF 2013-02-08 오전 5:24:31
 jek11  jek11님께 메시지 보내기jek11님을 내 주소록에 추가합니다.jek11님의 개인게시판 가기 번호: 161 추천:0  / 읽음:9,872

이번에는 프로젝트 관리 화면의 중단에 위치한 TreeView 를 구성해 보겠습니다.

이 Treeview 는 지난 글에 언급했듯이 BOS 어플리케이션의 메뉴를 트리 구조로 만들려고 사용한 것입니다.

 

처음 어플리케이션을 시작하면, 기본적으로 빈 공간이죠.

여기서 [New Prj] 를 클릭한거랑 같죠. 비우고 처음부터 다시 시작~

물론, [Open Prj] 를 클릭하면, 저장된 TreeView 구조를 불러와서 보여주면 되겠구요.

 

지금은 우선 TreeView 에 아이템을 추가하고 삭제하는 것을 하겠습니다.

 

 

지난 글에서 작업했던, 하단의 버튼들 있죠? 그중 [Add Item] 을 클릭했을 때를 처리하죠.

이 버튼을 클릭했을 때, TreeView 의 상태는 크게 2가지입니다.

 

1. 빈공간. 즉 TreeView 에 아이템이 한개도 없을때.

2. 한개 이상이 있을때.

 

그럼, 1번 상태인지 2번 상태인지를 확인하기 위해, TreeView 의 아이템 갯수를 확인하고.

1번 상태이면, 어플리케이션의 첫페이지는 항상 로그인이므로, 그냥 하드코딩으로 박아버립니다.

2번 상태이면, 먼저 아이템의 이름을 사용자로 부터 받습니다.

 

여기서 좀 골때리는 상황이 오는데요. C# 에는 VB 의 InputBox 같은게 없다고 합니다.

구글링 해본 결과, 사용자 입력을 달랑 하나 받는데에도, 사용자 정의 윈도우를 만들어야 한다고 하네요.

모...이런 XXX 같은 경우가 다 있는지...겨우 달랑...이름 하나 받는데...

 

그래서...찾아보니, 아래와 같은 글을 발견....

 

http://stackoverflow.com/questions/97097/what-is-the-c-sharp-version-of-vb-nets-inputdialog

 

요점은 솔루션 탐색기에 현재 프로젝트의 References 에 Microsoft.VisualBasic 을 추가하라는겁니다.

추가하고 나면, 아래와 같이 VB 의 InputBox 를 불러다 쓸수 있다는 겁니다.

추가하고 나면 이렇게 보입니다. 아래 "Microsft.VisualBasic" 이 추가된 겁니다.

 

 

 

 

 

즉, VB 에서 InputBox 가 구현되어 있는 DLL 을 불러다 쓰는거죠...몇번의 클릭으로 복잡한

DLL import 가 해결되고...좋네요...쓰기 편한데요...이기종의 함수를 이렇게 쉽게 불러다 쓰고....ㅋㅋㅋ

 

 

zItemName = Microsoft.VisualBasic.Interaction.InputBox("Enter a new name", "Add", "", -1, -1);

 

 

위의 코드로 사용자에게 새로 추가할 아이템의 이름을 받아옵니다.

Treeview 의 아이템 중 어느 아이템은 포커스가 있는 상태이니까,

포커스가 있는 (선택된) 아이템의 객체를 private 변수로 보관해둔 (SelectedItemChanged 이벤트에서),

그 보관된 변수, 즉 그 아이템의 자식으로 아이템을 추가하는 겁니다.

 

이때 주의할 것은 사용자가 입력한 값이 valid 한지 점검하는 코드를 추가하고

(왜냐면, 그냥 취소 버튼 누르거나, 입력상자를 그냥 닫아버리거나, 그냥 아무것도 안넣고 엔터키를 치는 경우는

아이템의 제목 없이 유령 아이템이 생깁니다...ㅎㅎ),

 

포커스가 갔을때 담아두었던, TreeViewItem 객체, tvSelectedItem 이 null 인지 아닌지를 확인합니다.

포커스가 한번도 안갔으면, 이 객체는 널 상태였겠죠. 그러니 확인을~~~

 

그래서, 여기까지의 코드가 아래와 같습니다.

 

 

private TreeViewItem tvSelectedItem;        // 아이템이 선택됐을때, 해당 아이템을 보관할 용도

                 

 

private void Button_Click_1(object sender, RoutedEventArgs e)

{

   // 추가할 아이템의 이름을 받아두는 변수입니다.
   String zItemName;

 

   // 추가할 아이템을 미리 만들어 둡니다.
   TreeViewItem
newChild = new TreeViewItem();

 

   if (BOS.Items.Count == 0)
   {
        // TreeView is blank.

        newChild.Header = "Login";

        BOS.Items.Add(newChild);
   }
   else
   {
        // Add a new item as child to the selected item.

        zItemName = Microsoft.VisualBasic.Interaction.InputBox("Enter a new name", "Add", "", -1, -1);

        zItemName = zItemName.Trim();

        if ((zItemName.Length > 0) && (tvSelectedItem != null))

        {

           newChild.Header = zItemName;

           tvSelectedItem.Items.Add(newChild);

        }        
   }

 

 

위의 코드를 잘 보면, newChild 가 생성해 놓고 한번도 참조가 안되는 경우가 발생하죠?

사용자가 아이템 이름을 안넣는 경우, newChild 는 한번도 사용이 안되죠.

그럼, 개발자가 임의로 free 를 시켜야 하나? 구글에서 사람들이 그러네요, 이런것 때문에 C# 쓴다구요.

어느 시점에 garbage collector 가 free 시켜주니까요.

 

 

그럼, 이제 언제 tvSelectedItem 이 선택된 아이템 객체를 보관하는지 알아보죠.

이것 때문에 몇시간 낭비했습니다. 아직도 이유는 모릅니다. 그냥. 이 이벤트가 아니라 저 이벤트를 써라~

 

처음 구글링 해보니...현재 선택된 아이템을 어떻게 확인하는지...

이렇게 하라고 써있네요.

 

XAML 에서,

 

<TreeView TreeViewItem.Selected="OnItemSelected"

 

그리고 cs 에서,

 

private void OnItemSelected(object sender, RoutedEventArgs e)

{

   tvSelectedItem = (sender as TreeViewItem);

   if ((sender as TreeViewItem) == null) MessageBox.Show("null!!!!");

}

 

했습니다. 그랬더니...이게 null 로 나오네요....헐.....이렇게 저렇게 해봐도 계속 null 로 나옵니다.

이벤트는 잘잡히구요. 아이템을 클릭하면, 위의 이벤트가 실행은 되는데 sender 가 널로 나와요...

참 답답할 노릇이죠... 왜 그러지... 그래서, 결국 데브피아의 질답에 물어보니, 답변을 받았습니다.

 

<TreeView Name="BOS" SelectedItemChanged="SelectionChanged"

 

SelectedItemChanged 라는 이벤트를 쓰라고요. 근데, 이벤트를 지정하는 방식이 제가 처음한거랑,

다르네요. 문법의 차이인지...모 여튼...다르지만..이유는 나중에 시간나면...찾아보고요..

일단..위의 방법이 작동을 하네요. 아래와 같이요.

 

 

private void SelectionChanged(object sender, RoutedPropertyChangedEventArgs<Object> e)

{

//Perform actions when SelectedItem changes

//MessageBox.Show(((TreeViewItem)e.NewValue).Header.ToString());

tvSelectedItem = (TreeViewItem)(sender as TreeView).SelectedItem;

}

 

 

여기까지 해서 빈공간의 Treeview 에 아이템을 사용자에게 받은 이름으로 추가하는것을 완성했습니다.

별거 아닌데..참 길게 느껴지네요.

 

지금...아이템 제거랑 이름 변경하는 코드를 작성하러 갑니다.

이 두가지가 완성되면...이 글 밑으로...다시 추가~~~~~~~~~

 

 

 

 

 

 

 

 

{

[코멘트] 좋음
2013-02-13 13:16
 best3286  best3286님께 메시지 보내기best3286님을 내 주소록에 추가합니다.best3286님의 개인게시판 가기 
TreeView의 Resources에 TreeViewItem 형식을 대상으로 Style을 정의하여 EventSetter로 ItemSelected이벤트를 할당해도 sender가 null인가요?
저장 취소
코멘트쓰기
  좋음   놀람   궁금   화남   슬픔   최고   침묵   시무룩   부끄럼   난감
* 코멘트는 500자 이내(띄어쓰기 포함)로 적어주세요.
목록 보기   지금 보고 계시는 글을 회원님의 my Mblog >> 스크랩에 넣어두고 다음에 바로 보실 수 있습니다.  
회사소개  |   개인정보취급방침  |  제휴문의  |   광고문의  |   E-Mail 무단수집거부  |   고객지원  |   이용안내  |   세금계산서
사업자등록번호 안내: 220-81-90008 / 통신판매업신고번호 제 2017-서울구로-0055호 / 대표: 홍영준, 서민호
08390, 서울시 구로구 디지털로32길 30, 1211호 / TEL. 02_6719_6200 / FAX. 02-6499-1910
Copyright ⓒ (주) 데브피아. All rights reserved.