TreeView Template 을 통한 Canvas 만들기




목차


그래픽 작업 관련된 툴을 개발하다보면, 캔버스를 사용할 일이 많습니다. 하지만 단순히 WPF 의 TreeView 를 가지고는 부족하지요.

Photoshop 을 예로 들면, 아래 그림처럼 Group 1 을 만들고, 그 안에 Layer 1 을 만듭니다. 그리고나서 Group 2를 만들고 Layer 2 를 만듭니다. 마지막으로 Group 2를 Group 1에 넣습니다.





이 상태에서 Group 1 을 이동하면, 안에 들어있는 Layer 1, Group 2 가 함께 움직입니다. 물론 Group 2 안에 있는 Layer 2 도 함께 움직이지요.




논리적인 구조나 상태 변화가 TreeView 처럼 동작합니다. Child 로 포함되어 있고, Parent 의 정보(위치)가 변경될때 Child 도 함께 변화되어야 하지요. 그 안에서 Child 의 변화는 Parent 에는 영향을 주지 않습니다.


이런 이유로 UI Control 을 새로 만들때, TreeView 를 사용하면 편합니다.

하지만, 기본 TreeView 의 모양은 우리가 원하는 생김새가 아니지요. 아래 그림처럼요.




이것을 우리 입맛에 맞게 수정하려면, Template 을 수정해야 합니다. 모양도 모양이지만, Layer 2 가 Layer 1 보다 앞쪽에(Z-index) 있어야 하지요.




개요


기본 구조는 Parent 나 Child 나 모두 Canvas 면 될듯 합니다. 이것이 핵심이죠.

코드가 간단하므로 별도 설명은 하지 않도록 하겠습니다. Template 을 직접 수정하면, 반복적인 스타일을 Child(TreeViewItem)에 적용할 수 없으므로, Style 을 통해서 변경해야 합니다. :)


참, 위치정보는 Canvas.Left, Canvas.Top 등을 이용하여 x, y 위치를 지정할 수 있습니다.






Style 로 정의하려면 아래처럼 됩니다.


    [TreeViewCanvas]



    <Style TargetType="{x:Type local:CanvasTreeView}">
        <Setter Property="Template">
            <Setter.Value>
                <ControlTemplate TargetType="{x:Type TreeView}">
                    <ControlTemplate.Resources>
                        <Style TargetType="{x:Type TreeViewItem}">
                            <Setter Property="Template">
                                <Setter.Value>
                                    <ControlTemplate TargetType="{x:Type TreeViewItem}">
                                        <Canvas>
                                            <ContentPresenter Content="{TemplateBinding Header}" ContentTemplate="{TemplateBinding HeaderTemplate}"
                                                              Canvas.Left="{Binding (Canvas.Left)}"
                                                                Canvas.Right="{Binding (Canvas.Right)}"
                                                                Canvas.Top="{Binding (Canvas.Top)}"
                                                                Canvas.Bottom="{Binding (Canvas.Bottom)}"/>
                                            <ItemsPresenter/>
                                        </Canvas>
                                    </ControlTemplate>
                                </Setter.Value>
                            </Setter>

                            <Setter Property="ItemsPanel">
                                <Setter.Value>
                                    <ItemsPanelTemplate>
                                        <Canvas/>
                                    </ItemsPanelTemplate>
                                </Setter.Value>
                            </Setter>
                        </Style>
                    </ControlTemplate.Resources>
                    <ScrollViewer Background="{TemplateBinding Background}" 
                              HorizontalScrollBarVisibility="{TemplateBinding ScrollViewer.HorizontalScrollBarVisibility}" 
                              VerticalScrollBarVisibility="{TemplateBinding ScrollViewer.VerticalScrollBarVisibility}"
                              CanContentScroll="{TemplateBinding ScrollViewer.CanContentScroll}"
                              PanningRatio="{TemplateBinding ScrollViewer.PanningRatio}"
                              PanningMode="{TemplateBinding ScrollViewer.PanningMode}"
                              Focusable="False">
                        <ItemsPresenter/>
                    </ScrollViewer>
                </ControlTemplate>
            </Setter.Value>
        </Setter>

        <Setter Property="ItemsPanel">
            <Setter.Value>
                <ItemsPanelTemplate>
                    <Canvas/>
                </ItemsPanelTemplate>
            </Setter.Value>
        </Setter>
    </Style>





'Microsoft > WPF' 카테고리의 다른 글

Expanding Canvas 만들기  (2) 2014.11.14
Drag Canvas 만들기  (0) 2014.11.13
MEF(Managed Extensibility Framework)  (1) 2014.05.19
화면에 노출되는 프로퍼티는?  (1) 2014.05.13
TypeConverter  (0) 2014.05.12