■ 컨트롤 템플리트 탐색하기

----------------------------------------------------------------------------------------------------


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

    }

}

 

----------------------------------------------------------------------------------------------------

Posted by 사용자 icodebroker
TAG

댓글을 달아 주세요