첨부 실행 코드는 나눔고딕코딩 폰트를 사용합니다.
본 블로그는 광고를 포함하고 있습니다.
광고 클릭에서 발생하는 수익금은 모두 블로그 콘텐츠 향상을 위해 쓰여집니다.

728x90
반응형
728x170

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
    }
}

 

728x90

 

▶ 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
    }
}

 

300x250

 

▶ 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 dummyElement = 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> classList = new SortedList<string, Type>();

            classList.Add(rootType.Name, rootType);

            foreach(Assembly assembly in assemblyList)
            {
                foreach(Type type in assembly.GetTypes())
                {
                    if(type.IsPublic && type.IsSubclassOf(rootType))
                    {
                        classList.Add(type.Name, type);
                    }
                }
            }

            TypeTreeViewItem rootTypeItem = new TypeTreeViewItem(rootType);

            Items.Add(rootTypeItem);

            AddDerivedClass(rootTypeItem, classList);
        }

        #endregion

        //////////////////////////////////////////////////////////////////////////////////////////////////// Method
        ////////////////////////////////////////////////////////////////////////////////////////// Private

        #region 파생 클래스 추가하기 - AddDerivedClass(parentItem, classList)

        /// <summary>
        /// 파생 클래스 추가하기
        /// </summary>
        /// <param name="parentItem">부모 항목</param>
        /// <param name="classList">클래스 리스트</param>
        private void AddDerivedClass(TypeTreeViewItem parentItem, SortedList<string, Type> classList)
        {
            foreach(KeyValuePair<string, Type> keyValuePair in classList)
            {
                if(keyValuePair.Value.BaseType == parentItem.Type)
                {
                    TypeTreeViewItem childItem = new TypeTreeViewItem(keyValuePair.Value);

                    parentItem.Items.Add(childItem);

                    AddDerivedClass(childItem, classList);
                }
            }
        }

        #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
    {
        //////////////////////////////////////////////////////////////////////////////////////////////////// Dependency Property
        ////////////////////////////////////////////////////////////////////////////////////////// Static
        //////////////////////////////////////////////////////////////////////////////// Public

        #region 타입 속성 - TypeProperty

        /// <summary>
        /// 타입 속성
        /// </summary>
        public static DependencyProperty TypeProperty = DependencyProperty.Register
        (
            "Type",
            typeof(Type),
            typeof(DependencyPropertyListView),
            new PropertyMetadata(null, new PropertyChangedCallback(TypePropertyChangedCallback))
        );

        #endregion

        //////////////////////////////////////////////////////////////////////////////////////////////////// Property
        ////////////////////////////////////////////////////////////////////////////////////////// Public

        #region 타입 - Type

        /// <summary>
        /// 타입
        /// </summary>
        public Type Type
        {
            set
            {
                SetValue(TypeProperty, value);
            }
            get
            {
                return (Type)GetValue(TypeProperty);
            }
        }

        #endregion

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

        #region 생성자 - DependencyPropertyListView()

        /// <summary>
        /// 생성자
        /// </summary>
        public DependencyPropertyListView()
        {
            GridView gridView = new GridView();

            View = gridView;

            #region Name 그리드 뷰 컬럼

            GridViewColumn nameGridViewColumn = new GridViewColumn();

            nameGridViewColumn.Header               = "Name";
            nameGridViewColumn.Width                = double.NaN;
            nameGridViewColumn.DisplayMemberBinding = new Binding("Name");

            gridView.Columns.Add(nameGridViewColumn);

            #endregion
            #region OwnerType 그리드 뷰 컬럼

            GridViewColumn ownerTypeGridViewColumn = new GridViewColumn();

            ownerTypeGridViewColumn.Header = "Owner";
            ownerTypeGridViewColumn.Width  = double.NaN;

            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  = double.NaN;

            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                = double.NaN;
            defaultGridViewColumn.DisplayMemberBinding = new Binding("DefaultMetadata.DefaultValue");

            gridView.Columns.Add(defaultGridViewColumn);

            #endregion
            #region ReadOnly 그리드 뷰 컬럼

            GridViewColumn readOnlyGridViewColumn = new GridViewColumn();

            readOnlyGridViewColumn.Header               = "Read-Only";
            readOnlyGridViewColumn.Width                = double.NaN;
            readOnlyGridViewColumn.DisplayMemberBinding = new Binding("ReadOnly");

            gridView.Columns.Add(readOnlyGridViewColumn);

            #endregion
            #region Flags 그리드 뷰 컬럼

            GridViewColumn flagsGridViewColumn = new GridViewColumn();

            flagsGridViewColumn.Header = "Flags";
            flagsGridViewColumn.Width  = double.NaN;

            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 타입 속성 변경시 콜백 처리하기 - TypePropertyChangedCallback(d, e)

        /// <summary>
        /// 타입 속성 변경시 콜백 처리하기
        /// </summary>
        /// <param name="d">의존 객체</param>
        /// <param name="e">이벤트 인자</param>
        private static void TypePropertyChangedCallback(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            DependencyPropertyListView listView = d as DependencyPropertyListView;

            Type type = e.NewValue as Type;

            listView.ItemsSource = null;

            if(type != null)
            {
                SortedList<string, DependencyProperty> list = new SortedList<string,DependencyProperty>();

                FieldInfo[] fieldInfoArray = type.GetFields();

                foreach(FieldInfo fieldInfo in fieldInfoArray)
                {
                    if(fieldInfo.FieldType == typeof(DependencyProperty))
                    {
                        list.Add(fieldInfo.Name, (DependencyProperty)fieldInfo.GetValue(null));
                    }
                }

                listView.ItemsSource = list.Values;

                GridView gridView = listView.View as GridView;

                if(gridView != null)
                {
                    foreach(GridViewColumn column in gridView.Columns)
                    {
                        column.Width = 0;
                        column.Width = double.NaN;
                    }
                }
            }
        }

        #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
    }
}
728x90
반응형
그리드형
Posted by 사용자 icodebroker

댓글을 달아 주세요