/// <summary>
        /// Добавление пользовательских элементов в палитру в зависимости от выбранных объектов
        /// </summary>
        private void ShowPropertiesControlsBySelection()
        {
            BtCollapseAll.Visibility = Visibility.Hidden;

            // Удаляем контролы свойств
            if (StackPanelProperties.Children.Count > 0)
            {
                StackPanelProperties.Children.Clear();
            }

            var psr = AcadUtils.Editor.SelectImplied();

            if (psr.Value == null || psr.Value.Count == 0)
            {
                // Очищаем панель описания
                ShowDescription(string.Empty);

                // hide message
                StckMaxObjectsSelectedMessage.Visibility = Visibility.Collapsed;
            }
            else
            {
                var maxSelectedObjects = MainSettings.Instance.MaxSelectedObjects;
                if (maxSelectedObjects == 0 || maxSelectedObjects >= psr.Value.Count)
                {
                    StckMaxObjectsSelectedMessage.Visibility = Visibility.Collapsed;

                    var objectIds = new List <ObjectId>();
                    using (AcadUtils.Document.LockDocument())
                    {
                        using (var tr = new OpenCloseTransaction())
                        {
                            foreach (SelectedObject selectedObject in psr.Value)
                            {
                                if (selectedObject.ObjectId == ObjectId.Null)
                                {
                                    continue;
                                }

                                var obj = tr.GetObject(selectedObject.ObjectId, OpenMode.ForRead);
                                if (obj is BlockReference blockReference &&
                                    ExtendedDataUtils.IsApplicable(blockReference))
                                {
                                    objectIds.Add(selectedObject.ObjectId);
                                }
                            }

                            tr.Commit();
                        }
                    }

                    if (objectIds.Any())
                    {
                        BtCollapseAll.Visibility = Visibility.Visible;
                        var summaryPropertyCollection = new SummaryPropertyCollection(objectIds);
                        summaryPropertyCollection.OnLockedLayerEventHandler +=
                            (sender, args) => ShowPropertiesControlsBySelection();
                        SetData(summaryPropertyCollection);
                    }
                }
                else
                {
                    StckMaxObjectsSelectedMessage.Visibility = Visibility.Visible;
                }
            }
        }
        /// <summary>
        /// Построение элементов в палитре по данным коллекции свойств
        /// </summary>
        /// <param name="collection"><see cref="SummaryPropertyCollection"/></param>
        public void SetData(SummaryPropertyCollection collection)
        {
            var different = $"*{ModPlusAPI.Language.GetItem("vc1")}*";

            var entityGroups = collection.Where(sp => sp.EntityPropertyDataCollection.Any())
                               .GroupBy(sp => sp.EntityType);

            foreach (var entityGroup in entityGroups)
            {
                // Тип примитива может содержать атрибуты указывающие зависимость видимости свойств
                // Собираю их в список для последующей работы
                var visibilityDependencyAttributes = GetVisibilityDependencyAttributes(entityGroup.Key);
                var allEntitySummaryProperties     = entityGroup.Select(g => g).ToList();

                var c = entityGroup.SelectMany(sp => sp.EntityPropertyDataCollection).Select(p => p.OwnerObjectId).Distinct().Count();
                var entityExpander = new Expander
                {
                    IsExpanded = true,
                    Header     = $"{LocalizationUtils.GetEntityLocalizationName(entityGroup.Key)} [{c}]",
                    Style      = Resources["EntityExpander"] as Style
                };

                var mainGrid = new Grid
                {
                    Visibility = Visibility.Collapsed,
                    Opacity    = 0.0
                };
                Transitions.SetOpacity(mainGrid, new OpacityParams
                {
                    From         = 0.0,
                    To           = 1.0,
                    Duration     = 300,
                    TransitionOn = TransitionOn.Visibility
                });
                var categoryIndex           = 0;
                var summaryPropertiesGroups = entityGroup.GroupBy(sp => sp.Category).ToList();
                summaryPropertiesGroups.Sort((sp1, sp2) => sp1.Key.CompareTo(sp2.Key));

                foreach (var summaryPropertiesGroup in summaryPropertiesGroups)
                {
                    mainGrid.RowDefinitions.Add(new RowDefinition {
                        Height = GridLength.Auto
                    });

                    var grid = new Grid();
                    Grid.SetRow(grid, categoryIndex);

                    var headerRowDefinition = new RowDefinition {
                        Height = GridLength.Auto
                    };
                    var firstColumn = new ColumnDefinition {
                        MinWidth = 50
                    };
                    BindingOperations.SetBinding(firstColumn, ColumnDefinition.WidthProperty, CreateBindingForColumnWidth());
                    var secondColumn = new ColumnDefinition {
                        Width = GridLength.Auto
                    };
                    var thirdColumn = new ColumnDefinition {
                        MinWidth = 50
                    };
                    grid.RowDefinitions.Add(headerRowDefinition);
                    grid.ColumnDefinitions.Add(firstColumn);
                    grid.ColumnDefinitions.Add(secondColumn);
                    grid.ColumnDefinitions.Add(thirdColumn);

                    var categoryHeader = new TextBox
                    {
                        Text = LocalizationUtils.GetCategoryLocalizationName(summaryPropertiesGroup.Key)
                    };
                    Grid.SetRow(categoryHeader, 0);
                    Grid.SetColumn(categoryHeader, 0);
                    Grid.SetColumnSpan(categoryHeader, 3);
                    categoryHeader.Style = Resources["HeaderTextBox"] as Style;
                    grid.Children.Add(categoryHeader);

                    // sort
                    var j = 1;
                    foreach (var summaryProperty in summaryPropertiesGroup.OrderBy(sp => sp.OrderIndex))
                    {
                        if (summaryProperty.PropertyScope == PropertyScope.Hidden)
                        {
                            continue;
                        }

                        var rowDefinition = new RowDefinition {
                            Height = GridLength.Auto
                        };
                        grid.RowDefinitions.Add(rowDefinition);

                        // property name
                        var propertyDescription = GetPropertyDescription(summaryProperty);
                        var propertyHeader      = new TextBox
                        {
                            Text  = GetPropertyDisplayName(summaryProperty),
                            Style = Resources["PropertyNameTextBox"] as Style
                        };
                        SetDescription(propertyHeader, propertyDescription);
                        SetVisibilityDependency(visibilityDependencyAttributes, allEntitySummaryProperties, summaryProperty.PropertyName, propertyHeader);
                        Grid.SetColumn(propertyHeader, 0);
                        Grid.SetRow(propertyHeader, j);
                        grid.Children.Add(propertyHeader);

                        var entityProperty = summaryProperty.EntityPropertyDataCollection.FirstOrDefault();

                        if (entityProperty != null)
                        {
                            if (summaryProperty.PropertyName == "Style")
                            {
                                try
                                {
                                    var cb = new ComboBox();
                                    Grid.SetColumn(cb, 2);
                                    Grid.SetRow(cb, j);
                                    cb.ItemsSource = StyleManager.GetStyles(entityProperty.EntityType).Select(s => s.Name);
                                    cb.Style       = Resources["PropertyValueComboBox"] as Style;
                                    SetDescription(cb, propertyDescription);
                                    SetVisibilityDependency(
                                        visibilityDependencyAttributes, allEntitySummaryProperties, summaryProperty.PropertyName, cb);
                                    SetForegroundBinding(cb, summaryProperty);
                                    BindingOperations.SetBinding(
                                        cb, ComboBox.TextProperty, CreateTwoWayBindingForProperty(summaryProperty));
                                    grid.Children.Add(cb);
                                }
                                catch (Exception exception)
                                {
                                    ExceptionBox.Show(exception);
                                }
                            }
                            else if (summaryProperty.PropertyName == "LayerName")
                            {
                                try
                                {
                                    var cb = new ComboBox();
                                    Grid.SetColumn(cb, 2);
                                    Grid.SetRow(cb, j);
                                    cb.ItemsSource = AcadUtils.Layers;
                                    cb.Style       = Resources["PropertyValueComboBox"] as Style;
                                    SetDescription(cb, propertyDescription);
                                    SetVisibilityDependency(
                                        visibilityDependencyAttributes, allEntitySummaryProperties, summaryProperty.PropertyName, cb);
                                    SetForegroundBinding(cb, summaryProperty);
                                    BindingOperations.SetBinding(
                                        cb, ComboBox.TextProperty, CreateTwoWayBindingForProperty(summaryProperty));
                                    grid.Children.Add(cb);
                                }
                                catch (Exception exception)
                                {
                                    ExceptionBox.Show(exception);
                                }
                            }
                            else if (summaryProperty.PropertyName == "Scale")
                            {
                                try
                                {
                                    var cb = new ComboBox();
                                    Grid.SetColumn(cb, 2);
                                    Grid.SetRow(cb, j);
                                    cb.ItemsSource = AcadUtils.Scales;
                                    cb.Style       = Resources["PropertyValueComboBox"] as Style;
                                    SetDescription(cb, propertyDescription);
                                    SetVisibilityDependency(
                                        visibilityDependencyAttributes, allEntitySummaryProperties, summaryProperty.PropertyName, cb);
                                    SetForegroundBinding(cb, summaryProperty);
                                    BindingOperations.SetBinding(
                                        cb, ComboBox.TextProperty, CreateTwoWayBindingForProperty(summaryProperty));
                                    grid.Children.Add(cb);
                                }
                                catch (Exception exception)
                                {
                                    ExceptionBox.Show(exception);
                                }
                            }
                            else if (summaryProperty.PropertyName == "LineType")
                            {
                                try
                                {
                                    var tb = new TextBox();
                                    Grid.SetColumn(tb, 2);
                                    Grid.SetRow(tb, j);
                                    tb.Style             = Resources["PropertyValueTextBoxClickable"] as Style;
                                    tb.PreviewMouseDown += LineType_OnPreviewMouseDown;
                                    SetDescription(tb, propertyDescription);
                                    SetVisibilityDependency(
                                        visibilityDependencyAttributes, allEntitySummaryProperties, summaryProperty.PropertyName, tb);
                                    SetForegroundBinding(tb, summaryProperty);
                                    BindingOperations.SetBinding(
                                        tb, TextBox.TextProperty, CreateTwoWayBindingForProperty(summaryProperty));
                                    grid.Children.Add(tb);
                                }
                                catch (Exception exception)
                                {
                                    ExceptionBox.Show(exception);
                                }
                            }
                            else if (summaryProperty.PropertyName.Contains("TextStyle"))
                            {
                                try
                                {
                                    var cb = new ComboBox();
                                    Grid.SetColumn(cb, 2);
                                    Grid.SetRow(cb, j);
                                    cb.ItemsSource = AcadUtils.TextStyles;
                                    cb.Style       = Resources["PropertyValueComboBox"] as Style;
                                    SetDescription(cb, propertyDescription);
                                    SetVisibilityDependency(
                                        visibilityDependencyAttributes, allEntitySummaryProperties, summaryProperty.PropertyName, cb);
                                    SetForegroundBinding(cb, summaryProperty);
                                    BindingOperations.SetBinding(
                                        cb, ComboBox.TextProperty, CreateTwoWayBindingForProperty(summaryProperty));
                                    grid.Children.Add(cb);
                                }
                                catch (Exception exception)
                                {
                                    ExceptionBox.Show(exception);
                                }
                            }
                            else if (entityProperty.Value is Enum)
                            {
                                try
                                {
                                    var cb = new ComboBox();
                                    Grid.SetColumn(cb, 2);
                                    Grid.SetRow(cb, j);
                                    cb.Style = Resources["PropertyValueComboBox"] as Style;
                                    var type = entityProperty.Value.GetType();
                                    SetDescription(cb, propertyDescription);
                                    SetVisibilityDependency(
                                        visibilityDependencyAttributes, allEntitySummaryProperties, summaryProperty.PropertyName, cb);
                                    cb.ItemsSource = LocalizationUtils.GetEnumPropertyLocalizationFields(type);
                                    cb.IsEnabled   = !entityProperty.IsReadOnly;
                                    SetForegroundBinding(cb, summaryProperty);

                                    BindingOperations.SetBinding(cb, ComboBox.TextProperty,
                                                                 CreateTwoWayBindingForProperty(summaryProperty, new EnumPropertyValueConverter()));

                                    grid.Children.Add(cb);
                                }
                                catch (Exception exception)
                                {
                                    ExceptionBox.Show(exception);
                                }
                            }
                            else if (entityProperty.Value is int)
                            {
                                try
                                {
                                    if (entityProperty.IsReadOnly)
                                    {
                                        var tb = new TextBox
                                        {
                                            Style = Resources["PropertyValueReadOnlyTextBox"] as Style
                                        };
                                        Grid.SetColumn(tb, 2);
                                        Grid.SetRow(tb, j);

                                        SetDescription(tb, propertyDescription);
                                        SetVisibilityDependency(visibilityDependencyAttributes, allEntitySummaryProperties, summaryProperty.PropertyName, tb);
                                        tb.Text = summaryProperty.IntValue.HasValue
                                            ? summaryProperty.IntValue.ToString()
                                            : different;

                                        grid.Children.Add(tb);
                                    }
                                    else
                                    {
                                        var numericBox = new NumericBox();
                                        Grid.SetColumn(numericBox, 2);
                                        Grid.SetRow(numericBox, j);
                                        numericBox.Minimum = summaryProperty.EntityPropertyDataCollection
                                                             .Select(p => Convert.ToInt32(p.Minimum)).Max();
                                        numericBox.Maximum = summaryProperty.EntityPropertyDataCollection
                                                             .Select(p => Convert.ToInt32(p.Maximum)).Min();
                                        numericBox.Interval         = 1.0;
                                        numericBox.NumericInputMode = NumericInput.Numbers;
                                        numericBox.Style            = Resources["PropertyValueNumericTextBox"] as Style;
                                        HintAssist.SetHint(numericBox, different);
                                        SetDescription(numericBox, propertyDescription);
                                        SetVisibilityDependency(
                                            visibilityDependencyAttributes,
                                            allEntitySummaryProperties,
                                            summaryProperty.PropertyName,
                                            numericBox);

                                        BindingOperations.SetBinding(
                                            numericBox,
                                            NumericBox.ValueProperty,
                                            CreateTwoWayBindingForPropertyForNumericValue(summaryProperty, true));

                                        grid.Children.Add(numericBox);
                                    }
                                }
                                catch (Exception exception)
                                {
                                    ExceptionBox.Show(exception);
                                }
                            }
                            else if (entityProperty.Value is double)
                            {
                                try
                                {
                                    if (entityProperty.IsReadOnly)
                                    {
                                        var tb = new TextBox
                                        {
                                            Style = Resources["PropertyValueReadOnlyTextBox"] as Style
                                        };
                                        Grid.SetColumn(tb, 2);
                                        Grid.SetRow(tb, j);
                                        SetDescription(tb, propertyDescription);
                                        SetVisibilityDependency(
                                            visibilityDependencyAttributes,
                                            allEntitySummaryProperties,
                                            summaryProperty.PropertyName,
                                            tb);
                                        tb.Text = summaryProperty.DoubleValue.HasValue
                                            ? summaryProperty.DoubleValue.ToString()
                                            : different;

                                        grid.Children.Add(tb);
                                    }
                                    else
                                    {
                                        var numericBox = new NumericBox();
                                        Grid.SetColumn(numericBox, 2);
                                        Grid.SetRow(numericBox, j);
                                        numericBox.Minimum = summaryProperty.EntityPropertyDataCollection
                                                             .Select(p => Convert.ToDouble(p.Minimum)).Max();
                                        numericBox.Maximum = summaryProperty.EntityPropertyDataCollection
                                                             .Select(p => Convert.ToDouble(p.Maximum)).Min();
                                        numericBox.NumericInputMode = NumericInput.Decimal;
                                        numericBox.Speedup          = true;
                                        numericBox.Interval         = 0.1;
                                        numericBox.Style            = Resources["PropertyValueNumericTextBox"] as Style;
                                        HintAssist.SetHint(numericBox, different);
                                        SetDescription(numericBox, propertyDescription);
                                        SetVisibilityDependency(
                                            visibilityDependencyAttributes,
                                            allEntitySummaryProperties,
                                            summaryProperty.PropertyName,
                                            numericBox);
                                        BindingOperations.SetBinding(
                                            numericBox,
                                            NumericBox.ValueProperty,
                                            CreateTwoWayBindingForPropertyForNumericValue(summaryProperty, false));

                                        grid.Children.Add(numericBox);
                                    }
                                }
                                catch (Exception exception)
                                {
                                    ExceptionBox.Show(exception);
                                }
                            }
                            else if (entityProperty.Value is bool)
                            {
                                try
                                {
                                    var chb = new CheckBox
                                    {
                                        Style = Resources["PropertyValueCheckBox"] as Style
                                    };
                                    SetDescription(chb, propertyDescription);
                                    SetVisibilityDependency(
                                        visibilityDependencyAttributes,
                                        allEntitySummaryProperties,
                                        summaryProperty.PropertyName,
                                        chb);
                                    chb.IsEnabled = !entityProperty.IsReadOnly;
                                    BindingOperations.SetBinding(
                                        chb,
                                        ToggleButton.IsCheckedProperty,
                                        CreateTwoWayBindingForProperty(summaryProperty));

                                    var outerBorder = new Border
                                    {
                                        Style = Resources["BorderForValueCheckBox"] as Style
                                    };
                                    Grid.SetColumn(outerBorder, 2);
                                    Grid.SetRow(outerBorder, j);

                                    outerBorder.Child = chb;
                                    grid.Children.Add(outerBorder);
                                }
                                catch (Exception exception)
                                {
                                    ExceptionBox.Show(exception);
                                }
                            }
                            else if (entityProperty.Value is string)
                            {
                                try
                                {
                                    var tb = new TextBox();
                                    Grid.SetColumn(tb, 2);
                                    Grid.SetRow(tb, j);
                                    tb.Style = Resources["PropertyValueTextBox"] as Style;
                                    SetDescription(tb, propertyDescription);
                                    SetVisibilityDependency(
                                        visibilityDependencyAttributes, allEntitySummaryProperties, summaryProperty.PropertyName, tb);
                                    SetForegroundBinding(tb, summaryProperty);
                                    BindingOperations.SetBinding(
                                        tb, TextBox.TextProperty, CreateTwoWayBindingForProperty(summaryProperty));
                                    tb.IsReadOnly = entityProperty.IsReadOnly;

                                    grid.Children.Add(tb);
                                }
                                catch (Exception exception)
                                {
                                    ExceptionBox.Show(exception);
                                }
                            }

                            j++;
                        }
                    }

                    grid.Children.Add(CreateGridSplitter(j));

                    mainGrid.Children.Add(grid);

                    categoryIndex++;
                }

                entityExpander.Content = mainGrid;

                StackPanelProperties.Children.Add(entityExpander);

                mainGrid.Visibility = Visibility.Visible;
            }
        }