WPF 팁

Form Designer 프로젝트 #4 - TreeView + XML 안떠니 평점: 10.0/10 (2명 참여) 조회: 4775
지금까지 삽질했다는 결론입니다. 앞에 두번에 걸친 TreeView 의 사용 설명을 그냥 WPF/C# 의 맛보기로 생각합시다.
TreeView 를 공부가 아닌 실무 어플리케이션에서 사용하려면, TreeView 의 내용을 저장하고, 불러오기는 기본이겠죠.
그러면, WPF/C# 에서는 접근 순서가 필요하다는걸 알게 되었습니다.

우선, TreeView 는 데이터의 UI 라는 것에서 부터 출발해야 합니다.
다른 툴을 경험하시 분이라면, 예를 들어, DB 의 내용을 뿌려주는 DBGrid, DataGrid 등의 비주얼 콤포넌트랑 같다는거죠.
이러한 비주얼 콤포넌트는 단지 DB 의 내용을 불러와서 네모난 상자에 뿌려주는거죠. Col, Row 에 맞춰서요.

자, 그럼, TreeView 는? 네, XML 이 가장 적합한 데이터겠죠. 모 DB 도 가능하겠지만.
DB 는 아직도 정형(ROW,COL 구분이 정해진) DB 가 보편적이고 기본이니까, TreeView 에는 적합하지 않죠.

DBGrid 에 DB 의 내용을 뿌리기 위해서는 우리가 DB 를 설계하죠?
TreeView 도 마찬가지로, XML 을 설계해야 합니다. 내가 데이터를 어떤 식으로 구성할 것인지, schema 를 생각해야죠.

이 프로젝트는 Back office 어플리케이션의 메뉴와 각 메뉴에 필요한 폼을 디자인하는 툴입니다.
그래서, 메뉴의 구조를 바탕으로 하기 때문에, XML 은 메뉴의 구조가 되어야 합니다.

각 노드가 하나의 메뉴가 될 것이기 때문에, 노드는 root 와 node, 이렇게 달랑 2개만 있으면 되겠죠.
그리고, 메뉴의 depth 에 따라서 각 노드가 생기면 되겠구요. 그래서, 다음과 같이...




Node 는 2개의 속성을 갖게 됩니다. name 는 메뉴의 이름을 갖게 되고, form 은 메뉴의 html 페이지 파일 이름을 갖게 됩니다. 물론, 이 파일 이름은 메뉴 이름의 <space> 를 "_" 로 변경하여 자동 생성시킵니다.

이렇게 root 노드와 Node 라는 노드, 달랑 2개와 각 노드에 2개의 속성을 지정하는 것으로 schema 를 완성합니다.
그리고, 코드에서는 NewProject() 가 실행됐을 때를 위해서 기본 xml 데이터를 다음과 같이 준비합니다.

        public void NewPrj()
        {
            // Remove all nodes.
            // Create XML with only <root name="Log-in"></root> by default.
            if (IsEditing == true)
            {
                MessageBox.Show("Please save the project first.", "Warning", MessageBoxButton.OK, MessageBoxImage.Warning);
            }
            else
            {
                BOS_XML.Document.RemoveAll();
                BOS_XML.Document.LoadXml("<root name='Log-in'></root>");
                BOS_XML.Refresh(); // To display the default node on Treeview.
            }           
        }



이제 스키마를 정리해 두었으니, 다음 단계로 XAML 에 있는 TreeView 를 data binding 할 수 있게 속성을 다음과 같이 지정합니다.


<Window x:Class="WpfApplication2.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="BOS Designer" Height="381" Width="310"
        ResizeMode="NoResize">

    <Window.Resources>
        <HierarchicalDataTemplate x:Key="NodeTemplate" DataType="Node" ItemsSource="{Binding XPath=*}">
            <TextBlock Text="{Binding Path=Attributes[0].Value}" />
        </HierarchicalDataTemplate>     
        <XmlDataProvider x:Key="BOS_MENU"></XmlDataProvider>

    </Window.Resources>


    <DockPanel HorizontalAlignment="Left" Height="350" LastChildFill="False" VerticalAlignment="Top" Width="297" Margin="0,0,-8,0">
        <Grid Height="340" VerticalAlignment="Top" Width="291">
        <Grid.RowDefinitions>
                <RowDefinition Height="31"/>
                <RowDefinition Height="*"/>
                <RowDefinition Height="28"/>
        </Grid.RowDefinitions>
            <Button Content="New Prj" Grid.Row="0" Height="31" VerticalAlignment="Top" Margin="0,0,221,0" Click="Button_Click_6"/>

   // .......................................................................  버튼 정의는 편의상...여기서는 생략...................................................

            <TreeView Name="BOS"
                      SelectedItemChanged="SelectionChanged" 
                      ItemsSource="{Binding Source={StaticResource BOS_MENU}, XPath=*}"
                      ItemTemplate="{StaticResource NodeTemplate}"

                      HorizontalAlignment="Left" Height="281" Margin="0,0,-6,0" Grid.Row="1" VerticalAlignment="Center" Width="297">
                <TreeView.ItemContainerStyle>
                    <Style TargetType="{x:Type TreeViewItem}">
                        <Setter Property="IsExpanded" Value="True"/>
                    </Style>
                    </TreeView.ItemContainerStyle>
            </TreeView>
        </Grid>
    </DockPanel>
</Window>



위의 코드 중에서,

<TextBlock Text="{Binding Path=Attributes[0].Value}" />

는 TreeView 의 각 노드에 표시할 이름을 노드의 첫번째, 즉 name 속성의 값으로 표시하겠다는 뜻입니다.

이제, xml 과 XAML 에서의 설정은 마무리 되었습니다.
이제, TreeView 는 XML 데이터로 바인딩이 되었으며, 이제 TreeView 의 각 아이템(=노드)는 XML 으로만 접근이 가능하게 되었습니다.

예를 들어서, 노드를 추가하려면, (이제부터 XML 과 바인딩된 관계로, 아이템 대신 노드라 부릅니다), 다음과 같이,

  XmlElement new_xElement = selected_xNode.OwnerDocument.CreateElement("Node");
  new_xElement.SetAttribute("name", zItemName);

  selected_xNode.AppendChild(new_xElement);


코드로 현재 선택된 노드에 자식 노드를 추가시키게 됩니다.


본격적인 추가/삭제/이름변경의 코드는 다음 글에서 설명하고, 이러한 코드를 위해서,
TreeView Manager 라는 클래스를 선언할 것입니다. 자 그럼...다음 글에서...











태그 : attributes binding data Treeview XML Xmldataprovider
작성자 정보
안떠니
Level 29
 [EXP.19/50]

메일:  비공개
글등록 +12 456 덧글등록 +3 249
자기소개
회사에서 WPF C# 으로 프로그램을 만들라고 하네요 ^^; (2013년) 2017년, Selenium, NUnit, ExtentReports 로 자동화를 하라고 하네요 ^^
글 공유하기 |
  tweet facebook
2013-02-16 오전 4:21:21
나도한마디
사용자
HOONS            [2013-02-16]
Level 99
 [EXP.만랩]
너무 좋은 예제가 될것 같네요 (^^)
글리스트
CheckBox ListBox 샘플[2] 파일첨부 이재웅
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에서 화면구조 보기 파일첨부 깜디
Canvas 의 Preview 기능 구현하기[1] 파일첨부 깊은물