WPF 팁

Form Designer 프로젝트 #5 - TreeView Manager 안떠니 평점: 10.0/10 (2명 참여) 조회: 3476
이번 글에서는 TreeView 에 노드를 추가/삭제/이름변경 하기 위한 작업을 설명합니다.
이러한 작업은 하나의 클래스로 정리하는 것이 코딩 편의상 좋기 때문에, 다음과 같이 메서드를 정리했습니다.




위의 메서드는 모두 첫번째 글에서 보여준 기능 버튼을 바탕으로 합니다.
새 프로젝트, 프로젝트 열기 등등이죠.

자, 이제 생성자 부터 살펴보겠습니다.

        // Constructor
        public TreeViewManager(TreeView tv, XmlDataProvider xml)
        {
            this.BOS_TV = tv;
            this.BOS_XML = xml;
        }


TreeViewManager 클래스의 인스턴스를 생성할 때 실행되며, 인자로 TreeView 와 xmldataprovider 를 전달합니다.
TreeView 는 노드를 추가/삭제하기 위해 전달하는 것이며, xmldataprovider 는 기존 xml 파일을 읽어와거나 새로운 프로젝트를 시작하기 위해서 TreeView 에 바인딩된 xml 을 변경하기 위해 전달하는 것입니다.

NewPrj() 는 이전 글에서 보여드렸구, 아래는 OpenPrj() 를 실행하는 코드입니다.


        // Open the existing xml file and bind it to TreeView.
        public void OpenPrj()
        {
             OpenFileDialog OD = new Microsoft.Win32.OpenFileDialog();
             OD.Filter = "XML Files (*.xml)|*.xml";
             if (OD.ShowDialog() == true)
             {
                 XmlDocument x = new XmlDocument();
                 x.Load(OD.FileName);
                 BOS_XML.Document = x;
             }            
        }


XmlDocument 형으로 임시 변수를 선언해서, 여기에 선택된 파일을 담아오고, 그 내용을 다시 xmldataprovider 에 전달하는 내용입니다. 코드는 참 간단해서 좋죠? 코딩은 단순 쉽게....

그리고, 저장하는 코드는 이어서....

        // Save XMLDocument bound to TreeView to the specified XML file.
        public void SavePrj()
        {
            SaveFileDialog SD = new Microsoft.Win32.SaveFileDialog();
            SD.Filter = "Text File (*.xml)|*.xml|Show All Files (*.*)|*.*";
            SD.FileName = "Untitled";
            SD.Title = "Save As";
            if (SD.ShowDialog() == true)
            {
                BOS_XML.Document.Save(SD.FileName);
                IsEditing = false;
            }
        }


별도의 설명이 필요없을 정도로, 코드가 무척 단순하죠....
IsEditing 은 TreeView 에서 추가/삭제..등의 작업을 하는 도중에 New Project 하는 것을 방지하기 위한 것입니다.
IsEditing 이 true 이면, 현재 작업 내용을 저장하라고 경고하는거죠. 저장을 하고나면, 다시 false 로 셋하구요.

이제, 가장 기본적인 노드의 추가입니다. 코드는 다음과 같습니다.

        // Add a new node to XMLDocument.
        public void AddNode()
        {
            String zFormName = "";
            XmlNode selected_xNode = this.BOS_TV.SelectedItem as XmlNode;   // 현재 treeview 에서 포커스가 있는
            if (selected_xNode.ParentNode.ParentNode != null)    // 노드의 최상위인 root 인지, 아닌지 확인
            {
                zFormName = selected_xNode.Attributes[0].Value.Replace(" ", "_");
            }
           
            if (selected_xNode != null)   // 안전하게 포커스가 있는 노드가 진짜 노드인지 빈 노드인지..확인...
            {
                zItemName = Microsoft.VisualBasic.Interaction.InputBox("Enter a new name", "Add", "", -1, -1);
                zItemName = zItemName.Trim();  // 입력받는 이름에서 앞뒤 공백 제거
                if (zItemName.Length > 0)  // 입력된 문자열이 있다면,
                {
                    XmlElement new_xElement = selected_xNode.OwnerDocument.CreateElement("Node");
                    new_xElement.SetAttribute("name", zItemName);  // name 속성에 입력 문자열을 저장
                    if (zItemName.IndexOf("Form") > 0)             // 메뉴 이름에 "Form" 문자열이 포함되었나?
                    {
                        new_xElement.SetAttribute("form", zFormName + "_" + zItemName.Substring(0, 1));
                    }
                    else
                    {
                        if (zFormName == "")
                        {
                            new_xElement.SetAttribute("form", zItemName.Replace(" ", "_"));
                        }
                        else
                        {
                            new_xElement.SetAttribute("form", zFormName);
                        }
                    }
                    selected_xNode.AppendChild(new_xElement);
                    IsEditing = true;
                }
            }
        }

위의 코드에서 뒷부분은 메뉴 이름에 Form 문자열이 있나 없나를 식별하고, 있으면, 거기에 따라 처리하는 것입니다.
Form 문자열이 있는 경우, 메뉴가 아닌 메뉴를 선택했을 때 나타나는 보고서 입력 화면 (보고서를 출력하기 위해 조건을 지정하는 화면, 가령 조회 시작 날짜, 끝 날짜 같은 조건값..), 또는 보고서 결과(출력) 화면입니다.


다음은 노드를 제거하는 코드입니다.

        // Remove the selected node from its parent node.
        public void RemoveNode()
        {
            XmlNode selected_xNode = BOS_TV.SelectedItem as XmlNode;
            XmlNode parent_xNode = selected_xNode.ParentNode;
            if (selected_xNode != null)
            {
                parent_xNode.RemoveChild(selected_xNode);
                IsEditing = true;
            }
        }


현재 노드의 부모 노드를 찾아서 null 이 아니면, 부모 노드에서 자식 노드를 삭제합니다.
그리고, 다음은 노드의 이름을 변경하는 코드입니다.

        // Rename the selected node.
        public void RenameNode()
        {
            String zOldName = "";
            XmlNode selected_xNode = BOS_TV.SelectedItem as XmlNode;
            if (selected_xNode != null)
            {
                zOldName = (BOS_TV.SelectedItem as XmlNode).Attributes[0].Value;
                zItemName = Microsoft.VisualBasic.Interaction.InputBox("Enter the name", "Rename", zOldName, -1, -1);
                zItemName = zItemName.Trim();
                if (zItemName.Length > 0)
                {
                    selected_xNode.Attributes[0].Value = zItemName;
                    selected_xNode.Attributes[1].Value.Replace(zOldName, zItemName);
                    BOS_TV.Items.Refresh();
                    IsEditing = true;
                }
            }
        }


이름을 변경하고 나면, Treeview 에 자동 refresh 가 안되기 때문에, Refresh() 메서드를 수동으로 호출합니다
여기서 문제는 Refresh() 를 하고 나면, Treeview 의 모든 노드가 collapsed 되어 버립니다.
이걸 막기 위해서, 그냥 쉽게.... Treeview 의 기본 속성을 

                <TreeView.ItemContainerStyle>
                    <Style TargetType="{x:Type TreeViewItem}">
                        <Setter Property="IsExpanded" Value="True"/>
                    </Style>
                    </TreeView.ItemContainerStyle>

이렇게 지정했습니다....펼쳤다...접었다...하는게 번거로우니...ㅡ그냥...늘 펴놓고 있는거죠 ^^; 쉽게 쉽게 ^^;



다음은 툴박스 윈도우를 만들고... 거기에서 [Button] 을 클릭할 때, 메인 윈도우에 버튼을 추가하고...삭제하는 작업을 진행하겠습니다. 완성되면요 ^^; 아직 삽질하고 있습니다.



<끝>





태그 : Treeview XML xmldataprovider
작성자 정보
안떠니
Level 28
 [EXP.46/50]

메일:  비공개
글등록 +12 444 덧글등록 +3 246
자기소개
회사에서 WPF C# 으로 프로그램을 만들라고 하네요 ^^;
글 공유하기 |
  tweet facebook
2013-02-16 오전 4:27:53
나도한마디
글리스트
CheckBox ListBox 샘플[1] 파일첨부 이재웅
RadioButton ListBox 샘플 파일첨부 이재웅
UniformGrid ListBox 샘플 파일첨부 이재웅
Horizontal ListBox 샘플 파일첨부 이재웅
Vertical ListBox 샘플[2] 파일첨부 이재웅
Form Designer 프로젝트 #7 - Tool Window (콘트롤 속성 지정/변경) - 완료![1]+1  안떠니
Form Designer 프로젝트 #6 - Tool Window (콘트롤 추가/삭제) - 완료![3]+1  안떠니
 ★현재글->   Form Designer 프로젝트 #5 - TreeView Manager  안떠니
Form Designer 프로젝트 #4 - TreeView + XML [1]  안떠니
Form Designer 프로젝트 #3 - TreeView 삭제 / 이름변경[2]+2  안떠니
Form Designer 프로젝트 #2 - TreeView 노드 추가[1]  안떠니
Form Designer 프로젝트 #1 - 프로젝트 관리 화면[4]+1  안떠니
실행파일에서 config 파일 변경하기[1]+3  킴언어
계산기[3]  sa2랑
WPF 성능관리  sa2랑
[RE] WPF Performance Suite  sa2랑
WPF에서 내부에서 작업한 내용을 UI에 올릴때 Dispatcher 클래스 사용[1]  지유니
VS와 Blend에서 화면구조 보기 파일첨부 깜디