<commit_before>﻿// --------------------------------------------------------------------------------------------------------------------
// <copyright file="PropertyGrid.cs" company="PropertyTools">
//   Copyright (c) 2014 PropertyTools contributors
// </copyright>
// <summary>
//   Specifies how the label widths are shared.
// </summary>
// --------------------------------------------------------------------------------------------------------------------

namespace PropertyTools.Wpf
{
    using System;
    using System.Collections;
    using System.Collections.Generic;
    using System.ComponentModel;
    using System.Diagnostics.CodeAnalysis;
    using System.Linq;
    using System.Windows;
    using System.Windows.Automation;
    using System.Windows.Controls;
    using System.Windows.Controls.Primitives;
    using System.Windows.Data;
    using System.Windows.Input;
    using System.Windows.Media;

    using PropertyTools.DataAnnotations;

    using HorizontalAlignment = System.Windows.HorizontalAlignment;

    /// <summary>
    /// Specifies how the label widths are shared.
    /// </summary>
    public enum LabelWidthSharing
    {
        /// <summary>
        /// The shared in tab.
        /// </summary>
        SharedInTab,

        /// <summary>
        /// The shared in group.
        /// </summary>
        SharedInGroup,

        /// <summary>
        /// The not shared.
        /// </summary>
        NotShared
    }

    /// <summary>
    /// Specifies the layout for checkboxes.
    /// </summary>
    public enum CheckBoxLayout
    {
        /// <summary>
        /// Show the header, then the check box without content
        /// </summary>
        Header,

        /// <summary>
        /// Hide the header, show the check box with the display name as content
        /// </summary>
        HideHeader,

        /// <summary>
        /// Collapse the header, show the check box with the display name as content
        /// </summary>
        CollapseHeader
    }

    /// <summary>
    /// Specifies the visibility of the tab strip.
    /// </summary>
    public enum TabVisibility
    {
        /// <summary>
        /// The tabs are visible.
        /// </summary>
        Visible,

        /// <summary>
        /// The tabs are visible if there is more than one tab.
        /// </summary>
        VisibleIfMoreThanOne,

        /// <summary>
        /// The tab strip is collapsed. The contents of the tab pages will be stacked vertically in the control. 
        /// </summary>
        Collapsed
    }

    /// <summary>
    /// The property control.
    /// </summary>
    [TemplatePart(Name = PartTabs, Type = typeof(TabControl))]
    [TemplatePart(Name = PartPanel, Type = typeof(StackPanel))]
    [TemplatePart(Name = PartScrollViewer, Type = typeof(ScrollViewer))]
    public class PropertyGrid : Control, IPropertyGridOptions
    {
        /// <summary>
        /// Identifies the <see cref="CategoryControlTemplate"/> dependency property.
        /// </summary>
        public static readonly DependencyProperty CategoryControlTemplateProperty =
            DependencyProperty.Register(
                "CategoryControlTemplate",
                typeof(ControlTemplate),
                typeof(PropertyGrid),
                new UIPropertyMetadata(null));

        /// <summary>
        /// Identifies the <see cref="CategoryControlType"/> dependency property.
        /// </summary>
        public static readonly DependencyProperty CategoryControlTypeProperty =
            DependencyProperty.Register(
                "CategoryControlType",
                typeof(CategoryControlType),
                typeof(PropertyGrid),
                new UIPropertyMetadata(CategoryControlType.GroupBox, AppearanceChanged));

        /// <summary>
        /// Identifies the <see cref="CategoryHeaderTemplate"/> dependency property.
        /// </summary>
        public static readonly DependencyProperty CategoryHeaderTemplateProperty =
            DependencyProperty.Register("CategoryHeaderTemplate", typeof(DataTemplate), typeof(PropertyGrid));

        /// <summary>
        /// Identifies the <see cref="DescriptionIconAlignment"/> dependency property.
        /// </summary>
        public static readonly DependencyProperty DescriptionIconAlignmentProperty =
            DependencyProperty.Register(
                "DescriptionIconAlignment",
                typeof(HorizontalAlignment),
                typeof(PropertyGrid),
                new UIPropertyMetadata(HorizontalAlignment.Right, AppearanceChanged));

        /// <summary>
        /// Identifies the <see cref="DescriptionIcon"/> dependency property.
        /// </summary>
        public static readonly DependencyProperty DescriptionIconProperty =
            DependencyProperty.Register("DescriptionIcon", typeof(ImageSource), typeof(PropertyGrid));

        /// <summary>
        /// Identifies the <see cref="EnableLabelWidthResizing"/> dependency property.
        /// </summary>
        public static readonly DependencyProperty EnableLabelWidthResizingProperty =
            DependencyProperty.Register(
                "EnableLabelWidthResizing",
                typeof(bool),
                typeof(PropertyGrid),
                new UIPropertyMetadata(true, AppearanceChanged));

        /// <summary>
        /// Identifies the <see cref="EnumAsRadioButtonsLimit"/> dependency property.
        /// </summary>
        public static readonly DependencyProperty EnumAsRadioButtonsLimitProperty =
            DependencyProperty.Register(
                "EnumAsRadioButtonsLimit",
                typeof(int),
                typeof(PropertyGrid),
                new UIPropertyMetadata(4, AppearanceChanged));

        /// <summary>
        /// Identifies the <see cref="LabelWidthSharing"/> dependency property.
        /// </summary>
        public static readonly DependencyProperty LabelWidthSharingProperty =
            DependencyProperty.Register(
                "LabelWidthSharing",
                typeof(LabelWidthSharing),
                typeof(PropertyGrid),
                new UIPropertyMetadata(LabelWidthSharing.SharedInTab, AppearanceChanged));

        /// <summary>
        /// Identifies the <see cref="MaximumLabelWidth"/> dependency property.
        /// </summary>
        public static readonly DependencyProperty MaximumLabelWidthProperty =
            DependencyProperty.Register(
                "MaximumLabelWidth", typeof(double), typeof(PropertyGrid), new UIPropertyMetadata(double.MaxValue));

        /// <summary>
        /// Identifies the <see cref="MinimumLabelWidth"/> dependency property.
        /// </summary>
        public static readonly DependencyProperty MinimumLabelWidthProperty =
            DependencyProperty.Register(
                "MinimumLabelWidth", typeof(double), typeof(PropertyGrid), new UIPropertyMetadata(70.0));

        /// <summary>
        /// Identifies the <see cref="MoveFocusOnEnter"/> dependency property.
        /// </summary>
        public static readonly DependencyProperty MoveFocusOnEnterProperty =
            DependencyProperty.Register(
                "MoveFocusOnEnter", typeof(bool), typeof(PropertyGrid), new UIPropertyMetadata(false));

        /// <summary>
        /// Identifies the <see cref="PropertyControlFactory"/> dependency property.
        /// </summary>
        public static readonly DependencyProperty PropertyControlFactoryProperty =
            DependencyProperty.Register(
                "PropertyControlFactory",
                typeof(IPropertyControlFactory),
                typeof(PropertyGrid),
                new UIPropertyMetadata(null));

        /// <summary>
        /// Identifies the <see cref="PropertyItem"/> dependency property.
        /// </summary>
        public static readonly DependencyProperty PropertyItemFactoryProperty =
            DependencyProperty.Register("PropertyItemFactory", typeof(IPropertyItemFactory), typeof(PropertyGrid));

        /// <summary>
        /// Identifies the <see cref="RequiredAttribute"/> dependency property.
        /// </summary>
        public static readonly DependencyProperty RequiredAttributeProperty =
            DependencyProperty.Register(
                "RequiredAttribute",
                typeof(Type),
                typeof(PropertyGrid),
                new UIPropertyMetadata(null, AppearanceChanged));

        /// <summary>
        /// Identifies the <see cref="SelectedObject"/> dependency property.
        /// </summary>
        public static readonly DependencyProperty SelectedObjectProperty = DependencyProperty.Register(
            "SelectedObject",
            typeof(object),
            typeof(PropertyGrid),
            new UIPropertyMetadata(null, (s, e) => ((PropertyGrid)s).OnSelectedObjectChanged(e)));

        /// <summary>
        /// Identifies the <see cref="SelectedObjects"/> dependency property.
        /// </summary>
        public static readonly DependencyProperty SelectedObjectsProperty =
            DependencyProperty.Register(
                "SelectedObjects",
                typeof(IEnumerable),
                typeof(PropertyGrid),
                new UIPropertyMetadata(null, (s, e) => ((PropertyGrid)s).SelectedObjectsChanged(e)));

        /// <summary>
        /// Identifies the <see cref="SelectedTabIndex"/> dependency property.
        /// </summary>
        public static readonly DependencyProperty SelectedTabIndexProperty =
            DependencyProperty.Register(
                "SelectedTabIndex",
                typeof(int),
                typeof(PropertyGrid),
                new FrameworkPropertyMetadata(0, (s, e) => ((PropertyGrid)s).SelectedTabIndexChanged(e)));

        /// <summary>
        /// The selected tab id property.
        /// </summary>
        public static readonly DependencyProperty SelectedTabIdProperty =
            DependencyProperty.Register(
                "SelectedTabId",
                typeof(string),
                typeof(PropertyGrid),
                new UIPropertyMetadata(null, (s, e) => ((PropertyGrid)s).SelectedTabChanged(e)));

        /// <summary>
        /// Identifies the <see cref="CheckBoxLayout"/> dependency property.
        /// </summary>
        public static readonly DependencyProperty CheckBoxLayoutProperty = DependencyProperty.Register(
            "CheckBoxLayout",
            typeof(CheckBoxLayout),
            typeof(PropertyGrid),
            new UIPropertyMetadata(CheckBoxLayout.Header, AppearanceChanged));

        /// <summary>
        /// Identifies the <see cref="ShowDeclaredOnly"/> dependency property.
        /// </summary>
        public static readonly DependencyProperty ShowDeclaredOnlyProperty =
            DependencyProperty.Register(
                "ShowDeclaredOnly",
                typeof(bool),
                typeof(PropertyGrid),
                new UIPropertyMetadata(false, AppearanceChanged));

        /// <summary>
        /// Identifies the <see cref="ShowDescriptionIcons"/> dependency property.
        /// </summary>
        public static readonly DependencyProperty ShowDescriptionIconsProperty =
            DependencyProperty.Register(
                "ShowDescriptionIcons",
                typeof(bool),
                typeof(PropertyGrid),
                new UIPropertyMetadata(true, AppearanceChanged));

        /// <summary>
        /// Identifies the <see cref="ShowReadOnlyProperties"/> dependency property.
        /// </summary>
        public static readonly DependencyProperty ShowReadOnlyPropertiesProperty =
            DependencyProperty.Register(
                "ShowReadOnlyProperties",
                typeof(bool),
                typeof(PropertyGrid),
                new UIPropertyMetadata(true, AppearanceChanged));

        /// <summary>
        /// Identifies the <see cref="TabHeaderTemplate"/> dependency property.
        /// </summary>
        public static readonly DependencyProperty TabHeaderTemplateProperty =
            DependencyProperty.Register("TabHeaderTemplate", typeof(DataTemplate), typeof(PropertyGrid));

        /// <summary>
        /// Identifies the <see cref="TabPageHeaderTemplate"/> dependency property.
        /// </summary>
        public static readonly DependencyProperty TabPageHeaderTemplateProperty =
            DependencyProperty.Register(
                "TabPageHeaderTemplate", typeof(DataTemplate), typeof(PropertyGrid), new UIPropertyMetadata(null));

        /// <summary>
        /// Identifies the <see cref="TabStripPlacement"/> dependency property.
        /// </summary>
        public static readonly DependencyProperty TabStripPlacementProperty =
            DependencyProperty.Register(
                "TabStripPlacement", typeof(Dock), typeof(PropertyGrid), new UIPropertyMetadata(Dock.Top));

        /// <summary>
        /// Identifies the <see cref="ToolTipTemplate"/> dependency property.
        /// </summary>
        public static readonly DependencyProperty ToolTipTemplateProperty =
            DependencyProperty.Register(
                "ToolTipTemplate", typeof(DataTemplate), typeof(PropertyGrid), new UIPropertyMetadata(null));

        /// <summary>
        /// Identifies the <see cref="TabVisibility"/> dependency property.
        /// </summary>
        public static readonly DependencyProperty TabVisibilityProperty = DependencyProperty.Register(
            "TabVisibility", typeof(TabVisibility), typeof(PropertyGrid), new UIPropertyMetadata(TabVisibility.Visible, AppearanceChanged));

        /// <summary>
        /// Identifies the <see cref="ValidationErrorStyle"/> dependency property.
        /// </summary>
        public static readonly DependencyProperty ValidationErrorStyleProperty =
            DependencyProperty.Register(
                "ValidationErrorStyle", typeof(Style), typeof(PropertyGrid), new UIPropertyMetadata(null));

        /// <summary>
        /// Identifies the <see cref="ValidationErrorTemplate"/> dependency property.
        /// </summary>
        public static readonly DependencyProperty ValidationErrorTemplateProperty =
            DependencyProperty.Register(
                "ValidationErrorTemplate", typeof(DataTemplate), typeof(PropertyGrid), new UIPropertyMetadata(null));

        /// <summary>
        /// Identifies the <see cref="ValidationTemplate"/> dependency property.
        /// </summary>
        public static readonly DependencyProperty ValidationTemplateProperty =
            DependencyProperty.Register(
                "ValidationTemplate", typeof(ControlTemplate), typeof(PropertyGrid), new UIPropertyMetadata(null));

        /// <summary>
        /// The panel part name.
        /// </summary>
        private const string PartPanel = "PART_Panel";

        /// <summary>
        /// The scroll control part name.
        /// </summary>
        private const string PartScrollViewer = "PART_ScrollViewer";

        /// <summary>
        /// The tab control part name.
        /// </summary>
        private const string PartTabs = "PART_Tabs";

        /// <summary>
        /// The value to visibility converter.
        /// </summary>
        private static readonly ValueToVisibilityConverter ValueToVisibilityConverter = new ValueToVisibilityConverter();

        /// <summary>
        /// The value to boolean converter.
        /// </summary>
        private static readonly ValueToBooleanConverter ValueToBooleanConverter = new ValueToBooleanConverter();

        /// <summary>
        /// Converts a list of values to a boolean value. Returns <c>true</c> if all values equal the converter parameter.
        /// </summary>
        private static readonly AllMultiValueConverter AllMultiValueConverter = new AllMultiValueConverter();

        /// <summary>
        /// The <c>null</c> to boolean converter.
        /// </summary>
        private static readonly NullToBoolConverter NullToBoolConverter = new NullToBoolConverter { NullValue = false };

        /// <summary>
        /// The zero to visibility converter.
        /// </summary>
        private static readonly ZeroToVisibilityConverter ZeroToVisibilityConverter = new ZeroToVisibilityConverter();

        /// <summary>
        /// The current selected object type.
        /// </summary>
        private Type currentSelectedObjectType;

        /// <summary>
        /// The panel control.
        /// </summary>
        private StackPanel panelControl;

        /// <summary>
        /// The scroll viewer.
        /// </summary>
        private ScrollViewer scrollViewer;

        /// <summary>
        /// The tab control.
        /// </summary>
        private TabControl tabControl;

        /// <summary>
        /// Initializes static members of the <see cref="PropertyGrid" /> class.
        /// </summary>
        static PropertyGrid()
        {
            DefaultStyleKeyProperty.OverrideMetadata(
                typeof(PropertyGrid), new FrameworkPropertyMetadata(typeof(PropertyGrid)));
        }

        /// <summary>
        /// Initializes a new instance of the <see cref="PropertyGrid" /> class.
        /// </summary>
        public PropertyGrid()
        {
            this.PropertyControlFactory = new DefaultPropertyControlFactory();
            this.PropertyItemFactory = new DefaultPropertyItemFactory();
        }

        /// <summary>
        /// Gets or sets the category control template.
        /// </summary>
        /// <value>The category control template.</value>
        public ControlTemplate CategoryControlTemplate
        {
            get
            {
                return (ControlTemplate)this.GetValue(CategoryControlTemplateProperty);
            }

            set
            {
                this.SetValue(CategoryControlTemplateProperty, value);
            }
        }

        /// <summary>
        /// Gets or sets the type of the category control.
        /// </summary>
        /// <value>The type of the category control.</value>
        public CategoryControlType CategoryControlType
        {
            get
            {
                return (CategoryControlType)this.GetValue(CategoryControlTypeProperty);
            }
<commit_msg>Fix #110<commit_after>﻿// --------------------------------------------------------------------------------------------------------------------
// <copyright file="PropertyGrid.cs" company="PropertyTools">
//   Copyright (c) 2014 PropertyTools contributors
// </copyright>
// <summary>
//   Specifies how the label widths are shared.
// </summary>
// --------------------------------------------------------------------------------------------------------------------

namespace PropertyTools.Wpf
{
    using System;
    using System.Collections;
    using System.Collections.Generic;
    using System.ComponentModel;
    using System.Diagnostics.CodeAnalysis;
    using System.Linq;
    using System.Windows;
    using System.Windows.Automation;
    using System.Windows.Controls;
    using System.Windows.Controls.Primitives;
    using System.Windows.Data;
    using System.Windows.Input;
    using System.Windows.Media;

    using PropertyTools.DataAnnotations;

    using HorizontalAlignment = System.Windows.HorizontalAlignment;

    /// <summary>
    /// Specifies how the label widths are shared.
    /// </summary>
    public enum LabelWidthSharing
    {
        /// <summary>
        /// The shared in tab.
        /// </summary>
        SharedInTab,

        /// <summary>
        /// The shared in group.
        /// </summary>
        SharedInGroup,

        /// <summary>
        /// The not shared.
        /// </summary>
        NotShared
    }

    /// <summary>
    /// Specifies the layout for checkboxes.
    /// </summary>
    public enum CheckBoxLayout
    {
        /// <summary>
        /// Show the header, then the check box without content
        /// </summary>
        Header,

        /// <summary>
        /// Hide the header, show the check box with the display name as content
        /// </summary>
        HideHeader,

        /// <summary>
        /// Collapse the header, show the check box with the display name as content
        /// </summary>
        CollapseHeader
    }

    /// <summary>
    /// Specifies the visibility of the tab strip.
    /// </summary>
    public enum TabVisibility
    {
        /// <summary>
        /// The tabs are visible.
        /// </summary>
        Visible,

        /// <summary>
        /// The tabs are visible if there is more than one tab.
        /// </summary>
        VisibleIfMoreThanOne,

        /// <summary>
        /// The tab strip is collapsed. The contents of the tab pages will be stacked vertically in the control. 
        /// </summary>
        Collapsed
    }

    /// <summary>
    /// The property control.
    /// </summary>
    [TemplatePart(Name = PartTabs, Type = typeof(TabControl))]
    [TemplatePart(Name = PartPanel, Type = typeof(StackPanel))]
    [TemplatePart(Name = PartScrollViewer, Type = typeof(ScrollViewer))]
    public class PropertyGrid : Control, IPropertyGridOptions
    {
        /// <summary>
        /// Identifies the <see cref="CategoryControlTemplate"/> dependency property.
        /// </summary>
        public static readonly DependencyProperty CategoryControlTemplateProperty =
            DependencyProperty.Register(
                "CategoryControlTemplate",
                typeof(ControlTemplate),
                typeof(PropertyGrid),
                new UIPropertyMetadata(null));

        /// <summary>
        /// Identifies the <see cref="CategoryControlType"/> dependency property.
        /// </summary>
        public static readonly DependencyProperty CategoryControlTypeProperty =
            DependencyProperty.Register(
                "CategoryControlType",
                typeof(CategoryControlType),
                typeof(PropertyGrid),
                new UIPropertyMetadata(CategoryControlType.GroupBox, AppearanceChanged));

        /// <summary>
        /// Identifies the <see cref="CategoryHeaderTemplate"/> dependency property.
        /// </summary>
        public static readonly DependencyProperty CategoryHeaderTemplateProperty =
            DependencyProperty.Register("CategoryHeaderTemplate", typeof(DataTemplate), typeof(PropertyGrid));

        /// <summary>
        /// Identifies the <see cref="DescriptionIconAlignment"/> dependency property.
        /// </summary>
        public static readonly DependencyProperty DescriptionIconAlignmentProperty =
            DependencyProperty.Register(
                "DescriptionIconAlignment",
                typeof(HorizontalAlignment),
                typeof(PropertyGrid),
                new UIPropertyMetadata(HorizontalAlignment.Right, AppearanceChanged));

        /// <summary>
        /// Identifies the <see cref="DescriptionIcon"/> dependency property.
        /// </summary>
        public static readonly DependencyProperty DescriptionIconProperty =
            DependencyProperty.Register("DescriptionIcon", typeof(ImageSource), typeof(PropertyGrid));

        /// <summary>
        /// Identifies the <see cref="EnableLabelWidthResizing"/> dependency property.
        /// </summary>
        public static readonly DependencyProperty EnableLabelWidthResizingProperty =
            DependencyProperty.Register(
                "EnableLabelWidthResizing",
                typeof(bool),
                typeof(PropertyGrid),
                new UIPropertyMetadata(true, AppearanceChanged));

        /// <summary>
        /// Identifies the <see cref="EnumAsRadioButtonsLimit"/> dependency property.
        /// </summary>
        public static readonly DependencyProperty EnumAsRadioButtonsLimitProperty =
            DependencyProperty.Register(
                "EnumAsRadioButtonsLimit",
                typeof(int),
                typeof(PropertyGrid),
                new UIPropertyMetadata(4, AppearanceChanged));

        /// <summary>
        /// Identifies the <see cref="LabelWidthSharing"/> dependency property.
        /// </summary>
        public static readonly DependencyProperty LabelWidthSharingProperty =
            DependencyProperty.Register(
                "LabelWidthSharing",
                typeof(LabelWidthSharing),
                typeof(PropertyGrid),
                new UIPropertyMetadata(LabelWidthSharing.SharedInTab, AppearanceChanged));

        /// <summary>
        /// Identifies the <see cref="MaximumLabelWidth"/> dependency property.
        /// </summary>
        public static readonly DependencyProperty MaximumLabelWidthProperty =
            DependencyProperty.Register(
                "MaximumLabelWidth", typeof(double), typeof(PropertyGrid), new UIPropertyMetadata(double.MaxValue));

        /// <summary>
        /// Identifies the <see cref="MinimumLabelWidth"/> dependency property.
        /// </summary>
        public static readonly DependencyProperty MinimumLabelWidthProperty =
            DependencyProperty.Register(
                "MinimumLabelWidth", typeof(double), typeof(PropertyGrid), new UIPropertyMetadata(70.0));

        /// <summary>
        /// Identifies the <see cref="MoveFocusOnEnter"/> dependency property.
        /// </summary>
        public static readonly DependencyProperty MoveFocusOnEnterProperty =
            DependencyProperty.Register(
                "MoveFocusOnEnter", typeof(bool), typeof(PropertyGrid), new UIPropertyMetadata(false));

        /// <summary>
        /// Identifies the <see cref="PropertyControlFactory"/> dependency property.
        /// </summary>
        public static readonly DependencyProperty PropertyControlFactoryProperty =
            DependencyProperty.Register(
                "PropertyControlFactory",
                typeof(IPropertyControlFactory),
                typeof(PropertyGrid),
                new UIPropertyMetadata(new DefaultPropertyControlFactory()));

        /// <summary>
        /// Identifies the <see cref="PropertyItem"/> dependency property.
        /// </summary>
        public static readonly DependencyProperty PropertyItemFactoryProperty =
            DependencyProperty.Register(
                "PropertyItemFactory", 
                typeof(IPropertyItemFactory), 
                typeof(PropertyGrid),
                new UIPropertyMetadata(new DefaultPropertyItemFactory()));

        /// <summary>
        /// Identifies the <see cref="RequiredAttribute"/> dependency property.
        /// </summary>
        public static readonly DependencyProperty RequiredAttributeProperty =
            DependencyProperty.Register(
                "RequiredAttribute",
                typeof(Type),
                typeof(PropertyGrid),
                new UIPropertyMetadata(null, AppearanceChanged));

        /// <summary>
        /// Identifies the <see cref="SelectedObject"/> dependency property.
        /// </summary>
        public static readonly DependencyProperty SelectedObjectProperty = DependencyProperty.Register(
            "SelectedObject",
            typeof(object),
            typeof(PropertyGrid),
            new UIPropertyMetadata(null, (s, e) => ((PropertyGrid)s).OnSelectedObjectChanged(e)));

        /// <summary>
        /// Identifies the <see cref="SelectedObjects"/> dependency property.
        /// </summary>
        public static readonly DependencyProperty SelectedObjectsProperty =
            DependencyProperty.Register(
                "SelectedObjects",
                typeof(IEnumerable),
                typeof(PropertyGrid),
                new UIPropertyMetadata(null, (s, e) => ((PropertyGrid)s).SelectedObjectsChanged(e)));

        /// <summary>
        /// Identifies the <see cref="SelectedTabIndex"/> dependency property.
        /// </summary>
        public static readonly DependencyProperty SelectedTabIndexProperty =
            DependencyProperty.Register(
                "SelectedTabIndex",
                typeof(int),
                typeof(PropertyGrid),
                new FrameworkPropertyMetadata(0, (s, e) => ((PropertyGrid)s).SelectedTabIndexChanged(e)));

        /// <summary>
        /// The selected tab id property.
        /// </summary>
        public static readonly DependencyProperty SelectedTabIdProperty =
            DependencyProperty.Register(
                "SelectedTabId",
                typeof(string),
                typeof(PropertyGrid),
                new UIPropertyMetadata(null, (s, e) => ((PropertyGrid)s).SelectedTabChanged(e)));

        /// <summary>
        /// Identifies the <see cref="CheckBoxLayout"/> dependency property.
        /// </summary>
        public static readonly DependencyProperty CheckBoxLayoutProperty = DependencyProperty.Register(
            "CheckBoxLayout",
            typeof(CheckBoxLayout),
            typeof(PropertyGrid),
            new UIPropertyMetadata(CheckBoxLayout.Header, AppearanceChanged));

        /// <summary>
        /// Identifies the <see cref="ShowDeclaredOnly"/> dependency property.
        /// </summary>
        public static readonly DependencyProperty ShowDeclaredOnlyProperty =
            DependencyProperty.Register(
                "ShowDeclaredOnly",
                typeof(bool),
                typeof(PropertyGrid),
                new UIPropertyMetadata(false, AppearanceChanged));

        /// <summary>
        /// Identifies the <see cref="ShowDescriptionIcons"/> dependency property.
        /// </summary>
        public static readonly DependencyProperty ShowDescriptionIconsProperty =
            DependencyProperty.Register(
                "ShowDescriptionIcons",
                typeof(bool),
                typeof(PropertyGrid),
                new UIPropertyMetadata(true, AppearanceChanged));

        /// <summary>
        /// Identifies the <see cref="ShowReadOnlyProperties"/> dependency property.
        /// </summary>
        public static readonly DependencyProperty ShowReadOnlyPropertiesProperty =
            DependencyProperty.Register(
                "ShowReadOnlyProperties",
                typeof(bool),
                typeof(PropertyGrid),
                new UIPropertyMetadata(true, AppearanceChanged));

        /// <summary>
        /// Identifies the <see cref="TabHeaderTemplate"/> dependency property.
        /// </summary>
        public static readonly DependencyProperty TabHeaderTemplateProperty =
            DependencyProperty.Register("TabHeaderTemplate", typeof(DataTemplate), typeof(PropertyGrid));

        /// <summary>
        /// Identifies the <see cref="TabPageHeaderTemplate"/> dependency property.
        /// </summary>
        public static readonly DependencyProperty TabPageHeaderTemplateProperty =
            DependencyProperty.Register(
                "TabPageHeaderTemplate", typeof(DataTemplate), typeof(PropertyGrid), new UIPropertyMetadata(null));

        /// <summary>
        /// Identifies the <see cref="TabStripPlacement"/> dependency property.
        /// </summary>
        public static readonly DependencyProperty TabStripPlacementProperty =
            DependencyProperty.Register(
                "TabStripPlacement", typeof(Dock), typeof(PropertyGrid), new UIPropertyMetadata(Dock.Top));

        /// <summary>
        /// Identifies the <see cref="ToolTipTemplate"/> dependency property.
        /// </summary>
        public static readonly DependencyProperty ToolTipTemplateProperty =
            DependencyProperty.Register(
                "ToolTipTemplate", typeof(DataTemplate), typeof(PropertyGrid), new UIPropertyMetadata(null));

        /// <summary>
        /// Identifies the <see cref="TabVisibility"/> dependency property.
        /// </summary>
        public static readonly DependencyProperty TabVisibilityProperty = DependencyProperty.Register(
            "TabVisibility", typeof(TabVisibility), typeof(PropertyGrid), new UIPropertyMetadata(TabVisibility.Visible, AppearanceChanged));

        /// <summary>
        /// Identifies the <see cref="ValidationErrorStyle"/> dependency property.
        /// </summary>
        public static readonly DependencyProperty ValidationErrorStyleProperty =
            DependencyProperty.Register(
                "ValidationErrorStyle", typeof(Style), typeof(PropertyGrid), new UIPropertyMetadata(null));

        /// <summary>
        /// Identifies the <see cref="ValidationErrorTemplate"/> dependency property.
        /// </summary>
        public static readonly DependencyProperty ValidationErrorTemplateProperty =
            DependencyProperty.Register(
                "ValidationErrorTemplate", typeof(DataTemplate), typeof(PropertyGrid), new UIPropertyMetadata(null));

        /// <summary>
        /// Identifies the <see cref="ValidationTemplate"/> dependency property.
        /// </summary>
        public static readonly DependencyProperty ValidationTemplateProperty =
            DependencyProperty.Register(
                "ValidationTemplate", typeof(ControlTemplate), typeof(PropertyGrid), new UIPropertyMetadata(null));

        /// <summary>
        /// The panel part name.
        /// </summary>
        private const string PartPanel = "PART_Panel";

        /// <summary>
        /// The scroll control part name.
        /// </summary>
        private const string PartScrollViewer = "PART_ScrollViewer";

        /// <summary>
        /// The tab control part name.
        /// </summary>
        private const string PartTabs = "PART_Tabs";

        /// <summary>
        /// The value to visibility converter.
        /// </summary>
        private static readonly ValueToVisibilityConverter ValueToVisibilityConverter = new ValueToVisibilityConverter();

        /// <summary>
        /// The value to boolean converter.
        /// </summary>
        private static readonly ValueToBooleanConverter ValueToBooleanConverter = new ValueToBooleanConverter();

        /// <summary>
        /// Converts a list of values to a boolean value. Returns <c>true</c> if all values equal the converter parameter.
        /// </summary>
        private static readonly AllMultiValueConverter AllMultiValueConverter = new AllMultiValueConverter();

        /// <summary>
        /// The <c>null</c> to boolean converter.
        /// </summary>
        private static readonly NullToBoolConverter NullToBoolConverter = new NullToBoolConverter { NullValue = false };

        /// <summary>
        /// The zero to visibility converter.
        /// </summary>
        private static readonly ZeroToVisibilityConverter ZeroToVisibilityConverter = new ZeroToVisibilityConverter();

        /// <summary>
        /// The current selected object type.
        /// </summary>
        private Type currentSelectedObjectType;

        /// <summary>
        /// The panel control.
        /// </summary>
        private StackPanel panelControl;

        /// <summary>
        /// The scroll viewer.
        /// </summary>
        private ScrollViewer scrollViewer;

        /// <summary>
        /// The tab control.
        /// </summary>
        private TabControl tabControl;

        /// <summary>
        /// Initializes static members of the <see cref="PropertyGrid" /> class.
        /// </summary>
        static PropertyGrid()
        {
            DefaultStyleKeyProperty.OverrideMetadata(
                typeof(PropertyGrid), new FrameworkPropertyMetadata(typeof(PropertyGrid)));
        }

        /// <summary>
        /// Gets or sets the category control template.
        /// </summary>
        /// <value>The category control template.</value>
        public ControlTemplate CategoryControlTemplate
        {
            get
            {
                return (ControlTemplate)this.GetValue(CategoryControlTemplateProperty);
            }

            set
            {
                this.SetValue(CategoryControlTemplateProperty, value);
            }
        }

        /// <summary>
        /// Gets or sets the type of the category control.
        /// </summary>
        /// <value>The type of the category control.</value>
        public CategoryControlType CategoryControlType
        {
            get
            {
                return (CategoryControlType)this.GetValue(CategoryControlTypeProperty);
            }

{'fraction_non_alphanumeric': 0.1143983677070696, 'fraction_numerical': 0.0005790228300430132, 'mean_word_length': 2.007629156646488, 'pattern_counts': {'":': 0, '<': 322, '<?xml version=': 0, '>': 330, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '3396861', 'n_tokens_mistral': 8176, 'n_tokens_neox': 7688, 'n_words': 2043}