■ 컨트롤 템플리트를 탐색하는 방법을 보여준다.
▶ ControlMenuItem.cs
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 |
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
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 |
<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
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 |
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 } } |