첨부 실행 코드는 나눔고딕코딩 폰트를 사용합니다.
유용한 소스 코드가 있으면 icodebroker@naver.com으로 보내주시면 감사합니다.
블로그 자료는 자유롭게 사용하세요.

728x90
반응형

TestProject.zip
다운로드

▶ ControlMenuItem.cs

using System;
using System.Collections.Generic;
using System.Reflection;
using System.Windows.Controls;

namespace TestProject
{
    /// <summary>
    /// 컨트롤 메뉴 항목
    /// </summary>
    public class ControlMenuItem : MenuItem
    {
        //////////////////////////////////////////////////////////////////////////////////////////////////// Constructor
        ////////////////////////////////////////////////////////////////////////////////////////// Public

        #region 생성자 - ControlMenuItem()

        /// <summary>
        /// 생성자
        /// </summary>
        public ControlMenuItem()
        {
            Assembly assembly = Assembly.GetAssembly(typeof(Control));

            Type[] typeArray = assembly.GetTypes();

            SortedList<string, MenuItem> menuItemSortedList = new SortedList<string, MenuItem>();

            Header = "Control";
            Tag    = typeof(Control);

            menuItemSortedList.Add("Control", this);

            foreach(Type type in typeArray)
            {
                if(type.IsPublic && (type.IsSubclassOf(typeof(Control))))
                {
                    MenuItem menuItem = new MenuItem();

                    menuItem.Header = type.Name;
                    menuItem.Tag    = type;

                    menuItemSortedList.Add(type.Name, menuItem);
                }
            }

            foreach(KeyValuePair<string, MenuItem> keyValuePair in menuItemSortedList)
            {
                if(keyValuePair.Key != "Control")
                {
                    string praentTypeName = ((Type)keyValuePair.Value.Tag).BaseType.Name;

                    MenuItem parentMenuItem = menuItemSortedList[praentTypeName];

                    parentMenuItem.Items.Add(keyValuePair.Value);
                }
            }

            foreach(KeyValuePair<string, MenuItem> keyValuePair in menuItemSortedList)
            {
                Type type = (Type)keyValuePair.Value.Tag;

                if(type.IsAbstract && keyValuePair.Value.Items.Count == 0)
                {
                    keyValuePair.Value.IsEnabled = false;
                }

                if(!type.IsAbstract && keyValuePair.Value.Items.Count > 0)
                {
                    MenuItem menuItem = new MenuItem();

                    menuItem.Header = keyValuePair.Value.Header as string;
                    menuItem.Tag    = type;

                    keyValuePair.Value.Items.Insert(0, menuItem);
                }
            }
        }

        #endregion
    }
}

 

▶ MainWindow.xaml

<Window x:Class="TestProject.MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:src="clr-namespace:TestProject"
    Width="800"
    Height="600"
    FontFamily="나눔고딕코딩"
    FontSize="16"
    Title="컨트롤 템플리트 탐색하기 - 미지정">
    <DockPanel>
        <Menu DockPanel.Dock="Top"
            FontSize="16">
            <src:ControlMenuItem MenuItem.Click="controlMenuItem_Click" />
            <MenuItem
                Header="Dump"
                SubmenuOpened="dumpMenuItem_SubmenuOpened">
                <MenuItem Name="templatePropertyMenuItem"
                    Header="Template 속성 (ControlTemplate 타입)"
                    Click="templatePropertyMenuItem_Click" />
                <MenuItem Name="itemsPanelPropertyMenuItem"
                    Header="ItemsPanel 속성(ItemsPanelTemplate 타입)"
                    Click="itemsPanelPropertyMenuItem_Click" />
            </MenuItem>
        </Menu>
        <Grid Name="grid">
            <Grid.RowDefinitions>
                <RowDefinition Height="2*"   />
                <RowDefinition Height="Auto" />
                <RowDefinition Height="8*"   />
            </Grid.RowDefinitions>
            <GridSplitter Grid.Row="1"
                HorizontalAlignment="Stretch"
                VerticalAlignment="Center"
                Height="6" />
            <TextBox Name="xamlTextBox" Grid.Row="2"
                HorizontalScrollBarVisibility="Auto"
                VerticalScrollBarVisibility="Auto"
                AcceptsReturn="True" />
        </Grid>
    </DockPanel>
</Window>

 

▶ MainWindow.cs

using System;
using System.Reflection;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Markup;
using System.Xml;

namespace TestProject
{
    /// <summary>
    /// 메인 윈도우
    /// </summary>
    public partial class MainWindow : Window
    {
        //////////////////////////////////////////////////////////////////////////////////////////////////// Field
        ////////////////////////////////////////////////////////////////////////////////////////// Private

        #region Field

        /// <summary>
        /// 컨트롤
        /// </summary>
        private Control control;

        #endregion

        //////////////////////////////////////////////////////////////////////////////////////////////////// Constructor
        ////////////////////////////////////////////////////////////////////////////////////////// Public

        #region 생성자 - MainWindow()

        /// <summary>
        /// 생성자
        /// </summary>
        public MainWindow()
        {
            InitializeComponent();
        }

        #endregion

        //////////////////////////////////////////////////////////////////////////////////////////////////// Method
        ////////////////////////////////////////////////////////////////////////////////////////// Static
        //////////////////////////////////////////////////////////////////////////////// Public

        #region 프로그램 시작하기 - Main()

        /// <summary>
        /// 프로그램 시작하기
        /// </summary>
        [STAThread]
        public static void Main()
        {
            Application application = new Application();

            application.Run(new MainWindow());
        }

        #endregion

        ////////////////////////////////////////////////////////////////////////////////////////// Instance
        //////////////////////////////////////////////////////////////////////////////// Private
        ////////////////////////////////////////////////////////////////////// Event

        #region 컨트롤 메뉴 항목 클릭시 처리하기 - controlMenuItem_Click(sender, e)

        /// <summary>
        /// 컨트롤 메뉴 항목 클릭시 처리하기
        /// </summary>
        /// <param name="sender">이벤트 발생자</param>
        /// <param name="e">이벤트 인자</param>
        private void controlMenuItem_Click(object sender, RoutedEventArgs e)
        {
            for(int i = 0; i < this.grid.Children.Count; i++)
            {
                if(Grid.GetRow(this.grid.Children[i]) == 0)
                {
                    this.grid.Children.Remove(this.grid.Children[i]);

                    break;
                }
            }

            xamlTextBox.Text = string.Empty;

            MenuItem menuItem = e.Source as MenuItem;

            Type type = (Type)menuItem.Tag;

            ConstructorInfo constructorInfo = type.GetConstructor(Type.EmptyTypes);

            try
            {
                control = (Control)constructorInfo.Invoke(null);
            }
            catch(Exception exception)
            {
                MessageBox.Show(exception.Message, Title);

                return;
            }

            try
            {
                this.grid.Children.Add(control);
            }
            catch
            {
                if(control is Window)
                {
                    (control as Window).Show();
                }
                else
                {
                    return;
                }
            }

            Title = Title.Remove(Title.IndexOf('-')) + "- " + type.Name;
        }

        #endregion
        #region Dump 메뉴 항목 하위 메뉴 오픈시 처리하기 - dumpMenuItem_SubmenuOpened(sender, e)

        /// <summary>
        /// Dump 메뉴 항목 하위 메뉴 오픈시 처리하기
        /// </summary>
        /// <param name="sender">이벤트 발생자</param>
        /// <param name="e">이벤트 인자</param>
        private void dumpMenuItem_SubmenuOpened(object sender, RoutedEventArgs e)
        {
            this.templatePropertyMenuItem.IsEnabled = control != null;

            this.itemsPanelPropertyMenuItem.IsEnabled = control != null && control is ItemsControl;
        }

        #endregion
        #region Template 속성 메뉴 항목 클릭시 처리하기 - templatePropertyMenuItem_Click(sender, e)

        /// <summary>
        /// Template 속성 메뉴 항목 클릭시 처리하기
        /// </summary>
        /// <param name="sender">이벤트 발생자</param>
        /// <param name="e">이벤트 인자</param>
        private void templatePropertyMenuItem_Click(object sender, RoutedEventArgs e)
        {
            if(this.control != null)
            {
                Dump(this.control.Template);
            }
        }

        #endregion
        #region ItemsPanel 속성 메뉴 항목 클릭시 처리하기 - itemsPanelPropertyMenuItem_Click(sender, e)

        /// <summary>
        /// ItemsPanel 속성 메뉴 항목 클릭시 처리하기
        /// </summary>
        /// <param name="sender">이벤트 발생자</param>
        /// <param name="e">이벤트 인자</param>
        private void itemsPanelPropertyMenuItem_Click(object sender, RoutedEventArgs e)
        {
            if(this.control != null && this.control is ItemsControl)
            {
                Dump((control as ItemsControl).ItemsPanel);
            }
        }

        #endregion

        ////////////////////////////////////////////////////////////////////// Function

        #region 덤프하기 - Dump(frameworkTemplate)

        /// <summary>
        /// 덤프하기
        /// </summary>
        /// <param name="frameworkTemplate">FrameworkTemplate 객체</param>
        private void Dump(FrameworkTemplate frameworkTemplate)
        {
            if(frameworkTemplate != null)
            {
                XmlWriterSettings xmlWriterSettings = new XmlWriterSettings();

                xmlWriterSettings.Indent              = true;
                xmlWriterSettings.IndentChars         = new string(' ', 4);
                xmlWriterSettings.NewLineOnAttributes = true;

                StringBuilder stringBuilder = new StringBuilder();

                XmlWriter xmlWriter = XmlWriter.Create(stringBuilder, xmlWriterSettings);

                try
                {
                    XamlWriter.Save(frameworkTemplate, xmlWriter);

                    this.xamlTextBox.Text = stringBuilder.ToString();
                }
                catch(Exception exception)
                {
                    this.xamlTextBox.Text = exception.Message;
                }
            }
            else
            {
                this.xamlTextBox.Text = "no template";
            }
        }

        #endregion
    }
}
728x90
반응형
Posted by 사용자 icodebroker
TAG , ,

댓글을 달아 주세요