■ 의존 속성 탐색하기

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


TestProject.zip


FPMToFPMOValueConverter.cs

 

 

using System;

using System.Globalization;

using System.Windows;

using System.Windows.Data;

 

namespace TestProject

{

    /// <summary>

    /// FrameworkPropertyMetadata ↔ FrameworkPropertyMetadataOptions 값 변환자

    /// </summary>

    public class FPMToFPMOValueConverter : IValueConverter

    {

        //////////////////////////////////////////////////////////////////////////////////////////////////// Method

        ////////////////////////////////////////////////////////////////////////////////////////// Public

 

        #region 변환하기 - Convert(value, type, parameter, cultureInfo)

 

        /// <summary>

        /// 변환하기

        /// </summary>

        /// <param name="value"></param>

        /// <param name="type">타입</param>

        /// <param name="parameter">매개 변수</param>

        /// <param name="cultureInfo">CultureInfo 객체</param>

        /// <returns>변환 값</returns>

        public object Convert(object value, Type type, object parameter, CultureInfo cultureInfo)

        {

            FrameworkPropertyMetadataOptions frameworkPropertyMetadataOptions = 0;

 

            FrameworkPropertyMetadata frameworkPropertyMetadata = value as FrameworkPropertyMetadata;

 

            if(frameworkPropertyMetadata == null)

            {

                return null;

            }

 

            if(frameworkPropertyMetadata.AffectsMeasure)

            {

                frameworkPropertyMetadataOptions |= FrameworkPropertyMetadataOptions.AffectsMeasure;

            }

 

            if(frameworkPropertyMetadata.AffectsArrange)

            {

                frameworkPropertyMetadataOptions |= FrameworkPropertyMetadataOptions.AffectsArrange;

            }

 

            if(frameworkPropertyMetadata.AffectsParentMeasure)

            {

                frameworkPropertyMetadataOptions |= FrameworkPropertyMetadataOptions.AffectsParentMeasure;

            }

 

            if(frameworkPropertyMetadata.AffectsParentArrange)

            {

                frameworkPropertyMetadataOptions |= FrameworkPropertyMetadataOptions.AffectsParentArrange;

            }

 

            if(frameworkPropertyMetadata.AffectsRender)

            {

                frameworkPropertyMetadataOptions |= FrameworkPropertyMetadataOptions.AffectsRender;

            }

 

            if(frameworkPropertyMetadata.Inherits)

            {

                frameworkPropertyMetadataOptions |= FrameworkPropertyMetadataOptions.Inherits;

            }

 

            if(frameworkPropertyMetadata.OverridesInheritanceBehavior)

            {

                frameworkPropertyMetadataOptions |= FrameworkPropertyMetadataOptions.OverridesInheritanceBehavior;

            }

 

            if(frameworkPropertyMetadata.IsNotDataBindable)

            {

                frameworkPropertyMetadataOptions |= FrameworkPropertyMetadataOptions.NotDataBindable;

            }

 

            if(frameworkPropertyMetadata.BindsTwoWayByDefault)

            {

                frameworkPropertyMetadataOptions |= FrameworkPropertyMetadataOptions.BindsTwoWayByDefault;

            }

 

            if(frameworkPropertyMetadata.Journal)

            {

                frameworkPropertyMetadataOptions |= FrameworkPropertyMetadataOptions.Journal;

            }

 

            return frameworkPropertyMetadataOptions;

        }

 

        #endregion

        #region 역변환하기 - ConvertBack(value, type, parameter, cultureInfo)

 

        /// <summary>

        /// 역변환하기

        /// </summary>

        /// <param name="value"></param>

        /// <param name="type">타입</param>

        /// <param name="parameter">매개 변수</param>

        /// <param name="cultureInfo">CultureInfo 객체</param>

        /// <returns>역변환 값</returns>

        public object ConvertBack(object value, Type type, object parameter, CultureInfo cultureInfo)

        {

            return new FrameworkPropertyMetadata(null, (FrameworkPropertyMetadataOptions)value);

        }

 

        #endregion

    }

}

 

 

TypeToTypeNameValueConverter.cs

 

 

using System;

using System.Globalization;

using System.Windows.Data;

 

namespace TestProject

{

    /// <summary>

    /// 타입→타입 명칭 값 변환자

    /// </summary>

    public class TypeToTypeNameValueConverter : IValueConverter

    {

        //////////////////////////////////////////////////////////////////////////////////////////////////// Method

        ////////////////////////////////////////////////////////////////////////////////////////// Public

 

        #region 변환하기 - Convert(value, type, parameter, cultureInfo)

 

        /// <summary>

        /// 변환하기

        /// </summary>

        /// <param name="value"></param>

        /// <param name="type">타입</param>

        /// <param name="parameter">매개 변수</param>

        /// <param name="cultureInfo">CultureInfo 객체</param>

        /// <returns>변환 값</returns>

        public object Convert(object value, Type type, object parameter, CultureInfo cultureInfo)

        {

            return (value as Type).Name;

        }

 

        #endregion

        #region 역변환하기 - ConvertBack(value, type, parameter, cultureInfo)

 

        /// <summary>

        /// 역변환하기

        /// </summary>

        /// <param name="value"></param>

        /// <param name="type">타입</param>

        /// <param name="parameter">매개 변수</param>

        /// <param name="cultureInfo">CultureInfo 객체</param>

        /// <returns>역변환 값</returns>

        public object ConvertBack(object value, Type type, object parameter, CultureInfo cultureInfo)

        {

            return null;

        }

 

        #endregion

    }

}

 

 

TypeTreeViewItem.cs

 

 

using System;

using System.Windows.Controls;

 

namespace TestProject

{

    /// <summary>

    /// 타입 트리 뷰 항목

    /// </summary>

    public class TypeTreeViewItem : TreeViewItem

    {

        //////////////////////////////////////////////////////////////////////////////////////////////////// Field

        ////////////////////////////////////////////////////////////////////////////////////////// Private

 

        #region Field

 

        /// <summary>

        /// 타입

        /// </summary>

        private Type type;

 

        #endregion

 

        //////////////////////////////////////////////////////////////////////////////////////////////////// Property

        ////////////////////////////////////////////////////////////////////////////////////////// Public

 

        #region 타입 - Type

 

        /// <summary>

        /// 타입

        /// </summary>

        public Type Type

        {

            set

            {

                this.type = value;

 

                if(this.type.IsAbstract)

                {

                    Header = this.type.Name + " (abstract)";

                }

                else

                {

                    Header = this.type.Name;

                }

            }

            get

            {

                return this.type;

            }

        }

 

        #endregion

 

        //////////////////////////////////////////////////////////////////////////////////////////////////// Constructor

        ////////////////////////////////////////////////////////////////////////////////////////// Public

 

        #region 생성자 - TypeTreeViewItem()

 

        /// <summary>

        /// 생성자

        /// </summary>

        public TypeTreeViewItem()

        {

        }

 

        #endregion

        #region 생성자 - TypeTreeViewItem(type)

 

        /// <summary>

        /// 생성자

        /// </summary>

        /// <param name="type">타입</param>

        public TypeTreeViewItem(Type type)

        {

            Type = type;

        }

 

        #endregion

    }

}

 

 

ClassHierarchyTreeView.cs

 

 

using System;

using System.Collections.Generic;

using System.Reflection;

using System.Windows;

using System.Windows.Controls;

 

namespace TestProject

{

    /// <summary>

    /// 클래스 계층 트리 뷰

    /// </summary>

    public class ClassHierarchyTreeView : TreeView

    {

        //////////////////////////////////////////////////////////////////////////////////////////////////// Constructor

        ////////////////////////////////////////////////////////////////////////////////////////// Public

 

        #region 생성자 - ClassHierarchyTreeView(rootType)

 

        /// <summary>

        /// 생성자

        /// </summary>

        /// <param name="rootType">루트 타입</param>

        public ClassHierarchyTreeView(Type rootType)

        {

            UIElement dummyUIElement = new UIElement();

 

            List<Assembly> assemblyList = new List<Assembly>();

 

            AssemblyName[] assemblyNameArray = Assembly.GetExecutingAssembly().GetReferencedAssemblies();

 

            foreach(AssemblyName assemblyName in assemblyNameArray)

            {

                assemblyList.Add(Assembly.Load(assemblyName));

            }

 

            SortedList<string, Type> classSortedList = new SortedList<string, Type>();

 

            classSortedList.Add(rootType.Name, rootType);

 

            foreach(Assembly assembly in assemblyList)

            {

                foreach(Type type in assembly.GetTypes())

                {

                    if(type.IsPublic && type.IsSubclassOf(rootType))

                    {

                        classSortedList.Add(type.Name, type);

                    }

                }

            }

 

            TypeTreeViewItem rootTypeTreeViewItem = new TypeTreeViewItem(rootType);

 

            Items.Add(rootTypeTreeViewItem);

 

            CreateDerivedClasses(rootTypeTreeViewItem, classSortedList);

        }

 

        #endregion

 

        //////////////////////////////////////////////////////////////////////////////////////////////////// Method

        ////////////////////////////////////////////////////////////////////////////////////////// Private

 

        #region 파생 클래스 생성하기 - CreateDerivedClasses(baseTypeTreeViewItem, classSortedList)

 

        /// <summary>

        /// 파생 클래스 생성하기

        /// </summary>

        /// <param name="baseTypeTreeViewItem">베이스 타입 트리 뷰 항목</param>

        /// <param name="classSortedList">클래스 정렬 리스트</param>

        private void CreateDerivedClasses(TypeTreeViewItem baseTypeTreeViewItem, SortedList<string, Type> classSortedList)

        {

            foreach(KeyValuePair<string, Type> keyValuePair in classSortedList)

            {

                if(keyValuePair.Value.BaseType == baseTypeTreeViewItem.Type)

                {

                    TypeTreeViewItem typeTreeViewItem = new TypeTreeViewItem(keyValuePair.Value);

 

                    baseTypeTreeViewItem.Items.Add(typeTreeViewItem);

 

                    CreateDerivedClasses(typeTreeViewItem, classSortedList);

                }

            }

        }

 

        #endregion

    }

}

 

 

DependencyPropertyListView.cs

 

 

using System;

using System.Collections.Generic;

using System.Reflection;

using System.Windows;

using System.Windows.Controls;

using System.Windows.Data;

 

namespace TestProject

{

    /// <summary>

    /// 의존 속성 리스트 뷰

    /// </summary>

    public class DependencyPropertyListView : ListView

    {

        //////////////////////////////////////////////////////////////////////////////////////////////////// Field

        ////////////////////////////////////////////////////////////////////////////////////////// Public

 

        #region Field

 

        /// <summary>

        /// 타입 속성

        /// </summary>

        public static DependencyProperty TypeProperty;

 

        #endregion

 

        //////////////////////////////////////////////////////////////////////////////////////////////////// Property

        ////////////////////////////////////////////////////////////////////////////////////////// Public

 

        #region 타입 - Type

 

        /// <summary>

        /// 타입

        /// </summary>

        public Type Type

        {

            set

            {

                SetValue(TypeProperty, value);

            }

            get

            {

                return (Type)GetValue(TypeProperty);

            }

        }

 

        #endregion

 

        //////////////////////////////////////////////////////////////////////////////////////////////////// Constructor

        ////////////////////////////////////////////////////////////////////////////////////////// Static

 

        #region 생성자 - DependencyPropertyListView()

 

        /// <summary>

        /// 생성자

        /// </summary>

        static DependencyPropertyListView()

        {

            TypeProperty = DependencyProperty.Register

            (

                "Type",

                typeof(Type),

                typeof(DependencyPropertyListView),

                new PropertyMetadata(null, new PropertyChangedCallback(Type_PropertyChanged))

            );

        }

 

        #endregion

 

        ////////////////////////////////////////////////////////////////////////////////////////// Instance

        //////////////////////////////////////////////////////////////////////////////// Public

 

        #region 생성자 - DependencyPropertyListView()

 

        /// <summary>

        /// 생성자

        /// </summary>

        public DependencyPropertyListView()

        {

            GridView gridView = new GridView();

 

            View = gridView;

 

            #region Name 그리드 뷰 컬럼

 

            GridViewColumn nameGridViewColumn = new GridViewColumn();

 

            nameGridViewColumn.Header               = "Name";

            nameGridViewColumn.Width                = 150;

            nameGridViewColumn.DisplayMemberBinding = new Binding("Name");

 

            gridView.Columns.Add(nameGridViewColumn);

 

            #endregion

            #region OwnerType 그리드 뷰 컬럼

 

            GridViewColumn ownerTypeGridViewColumn = new GridViewColumn();

 

            ownerTypeGridViewColumn.Header = "Owner";

            ownerTypeGridViewColumn.Width  = 100;

 

            gridView.Columns.Add(ownerTypeGridViewColumn);

 

            DataTemplate ownerTypeDataTemplate = new DataTemplate();

 

            ownerTypeGridViewColumn.CellTemplate = ownerTypeDataTemplate;

 

            FrameworkElementFactory ownerTypeTextBlockFrameworkElementFactory = new FrameworkElementFactory(typeof(TextBlock));

 

            ownerTypeDataTemplate.VisualTree = ownerTypeTextBlockFrameworkElementFactory;

 

            Binding ownerTypeBinding = new Binding("OwnerType");

 

            ownerTypeBinding.Converter = new TypeToTypeNameValueConverter();

 

            ownerTypeTextBlockFrameworkElementFactory.SetBinding(TextBlock.TextProperty, ownerTypeBinding);

 

            #endregion

            #region PropertyType 그리드 뷰 컬럼

 

            GridViewColumn propertyTypeGridViewColumn = new GridViewColumn();

 

            propertyTypeGridViewColumn.Header = "Type";

            propertyTypeGridViewColumn.Width  = 100;

 

            gridView.Columns.Add(propertyTypeGridViewColumn);

 

            DataTemplate propertyTypeDataTemplate = new DataTemplate();

 

            propertyTypeGridViewColumn.CellTemplate = propertyTypeDataTemplate;

 

            FrameworkElementFactory propertyTypeTextBlockFrameworkElementFactory = new FrameworkElementFactory(typeof(TextBlock));

 

            propertyTypeDataTemplate.VisualTree = propertyTypeTextBlockFrameworkElementFactory;

 

            Binding propertyTypeBinding = new Binding("PropertyType");

 

            propertyTypeBinding.Converter = new TypeToTypeNameValueConverter();

 

            propertyTypeTextBlockFrameworkElementFactory.SetBinding(TextBlock.TextProperty, propertyTypeBinding);

 

            #endregion

            #region Default 그리드 뷰 컬럼

 

            GridViewColumn defaultGridViewColumn = new GridViewColumn();

 

            defaultGridViewColumn.Header               = "Default";

            defaultGridViewColumn.Width                = 75;

            defaultGridViewColumn.DisplayMemberBinding = new Binding("DefaultMetadata.DefaultValue");

 

            gridView.Columns.Add(defaultGridViewColumn);

 

            #endregion

            #region ReadOnly 그리드 뷰 컬럼

 

            GridViewColumn readOnlyGridViewColumn = new GridViewColumn();

 

            readOnlyGridViewColumn.Header               = "Read-Only";

            readOnlyGridViewColumn.Width                = 75;

            readOnlyGridViewColumn.DisplayMemberBinding = new Binding("DefaultMetadata.IsReadOnly");

 

            gridView.Columns.Add(readOnlyGridViewColumn);

 

            #endregion

            #region Usage 그리드 뷰 컬럼

 

            GridViewColumn usageGridViewColumn = new GridViewColumn();

 

            usageGridViewColumn.Header               = "Usage";

            usageGridViewColumn.Width                = 75;

            usageGridViewColumn.DisplayMemberBinding = new Binding("DefaultMetadata.AttachedPropertyUsage");

 

            gridView.Columns.Add(usageGridViewColumn);

 

            #endregion

            #region Flags 그리드 뷰 컬럼

 

            GridViewColumn flagsGridViewColumn = new GridViewColumn();

 

            flagsGridViewColumn.Header = "Flags";

            flagsGridViewColumn.Width  = 250;

 

            gridView.Columns.Add(flagsGridViewColumn);

 

            DataTemplate flagsDataTemplate = new DataTemplate();

 

            flagsGridViewColumn.CellTemplate = flagsDataTemplate;

 

            FrameworkElementFactory flagsTextBlockFrameworkElementFactory = new FrameworkElementFactory(typeof(TextBlock));

 

            flagsDataTemplate.VisualTree = flagsTextBlockFrameworkElementFactory;

 

            Binding flagsBinding = new Binding("DefaultMetadata");

 

            flagsBinding.Converter = new FPMToFPMOValueConverter();

 

            flagsTextBlockFrameworkElementFactory.SetBinding(TextBlock.TextProperty, flagsBinding);

 

            #endregion

        }

 

        #endregion

 

        //////////////////////////////////////////////////////////////////////////////////////////////////// Method

        ////////////////////////////////////////////////////////////////////////////////////////// Static

        //////////////////////////////////////////////////////////////////////////////// Private

 

        #region 타입 속성 변경시 처리하기 - Type_PropertyChanged(dependencyObject, e)

 

        /// <summary>

        /// 타입 속성 변경시 처리하기

        /// </summary>

        /// <param name="dependencyObject">이벤트 발생자</param>

        /// <param name="e">이벤트 인자</param>

        private static void Type_PropertyChanged(DependencyObject dependencyObject, DependencyPropertyChangedEventArgs e)

        {

            DependencyPropertyListView dependencyPropertyListView = dependencyObject as DependencyPropertyListView;

 

            Type type = e.NewValue as Type;

 

            dependencyPropertyListView.ItemsSource = null;

 

            if(type != null)

            {

                SortedList<string, DependencyProperty> sortedList = new SortedList<string,DependencyProperty>();

 

                FieldInfo[] fieldInfoArray = type.GetFields();

 

                foreach(FieldInfo fieldInfo in fieldInfoArray)

                {

                    if(fieldInfo.FieldType == typeof(DependencyProperty))

                    {

                        sortedList.Add(fieldInfo.Name, (DependencyProperty)fieldInfo.GetValue(null));

                    }

                }

 

                dependencyPropertyListView.ItemsSource = sortedList.Values;

            }

        }

 

        #endregion

    }

}

 

 

MainWindow.cs

 

 

using System;

using System.Windows;

using System.Windows.Controls;

using System.Windows.Media;

 

namespace TestProject

{

    /// <summary>

    /// 메인 윈도우

    /// </summary>

    public class MainWindow : Window

    {

        //////////////////////////////////////////////////////////////////////////////////////////////////// Constructor

        ////////////////////////////////////////////////////////////////////////////////////////// Public

 

        #region 생성자 - ExploreDependencyProperties()

 

        /// <summary>

        /// 생성자

        /// </summary>

        public MainWindow()

        {

            Width      = 800;

            Height     = 600;

            Title      = "의존 속성 탐색하기";

            FontFamily = new FontFamily("나눔고딕코딩");

            FontSize   = 16;

 

            Grid grid = new Grid();

 

            Content = grid;

 

            #region 왼쪽 컬럼 정의를 생성한다.

 

            ColumnDefinition leftColumnDefinition = new ColumnDefinition();

 

            leftColumnDefinition.Width = new GridLength(1, GridUnitType.Star);

 

            grid.ColumnDefinitions.Add(new ColumnDefinition());

 

            #endregion

            #region 가운데 컬럼 정의를 생성한다.

 

            ColumnDefinition centerColumnDefinition = new ColumnDefinition();

 

            centerColumnDefinition.Width = GridLength.Auto;

 

            grid.ColumnDefinitions.Add(centerColumnDefinition);

 

            #endregion

            #region 오른쪽 컬럼 정의를 생성한다.

 

            ColumnDefinition rightColumnDefinition = new ColumnDefinition();

 

            rightColumnDefinition.Width = new GridLength(3, GridUnitType.Star);

 

            grid.ColumnDefinitions.Add(rightColumnDefinition);

 

            #endregion

 

            #region 클래스 계층 트리 뷰를 생성한다.

 

            ClassHierarchyTreeView classHierarchyTreeView = new ClassHierarchyTreeView(typeof(DependencyObject));

 

            grid.Children.Add(classHierarchyTreeView);

 

            Grid.SetColumn(classHierarchyTreeView, 0);

 

            #endregion

            #region 그리드 스플리터를 생성한다.

 

            GridSplitter gridSplitter = new GridSplitter();

 

            gridSplitter.HorizontalAlignment = HorizontalAlignment.Center;

            gridSplitter.VerticalAlignment   = VerticalAlignment.Stretch;

            gridSplitter.Width               = 6;

 

            grid.Children.Add(gridSplitter);

 

            Grid.SetColumn(gridSplitter, 1);

 

            #endregion

            #region 의존 속성 리스트 뷰를 생성한다.

 

            DependencyPropertyListView dependencyPropertyListView = new DependencyPropertyListView();

 

            grid.Children.Add(dependencyPropertyListView);

 

            Grid.SetColumn(dependencyPropertyListView, 2);

 

            #endregion

 

            dependencyPropertyListView.SetBinding(DependencyPropertyListView.TypeProperty, "SelectedItem.Type");

 

            dependencyPropertyListView.DataContext = classHierarchyTreeView;

        }

 

        #endregion

 

        //////////////////////////////////////////////////////////////////////////////////////////////////// Method

        ////////////////////////////////////////////////////////////////////////////////////////// Static

        //////////////////////////////////////////////////////////////////////////////// Public

 

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

 

        /// <summary>

        /// 프로그램 시작하기

        /// </summary>

        [STAThread]

        public static void Main()

        {

            Application application = new Application();

 

            application.Run(new MainWindow());

        }

 

        #endregion

    }

}

 

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

Posted by 사용자 icodebroker
TAG

댓글을 달아 주세요