protected virtual Control CreateTextBoxControl(
            ConfigurablePropertyMetadata property,
            IEnumerable <ConfigurablePropertyMetadata> allProperties)
        {
            var ctrlTextBox = new TextBox();

            ctrlTextBox[!TextBox.TextProperty] = new Binding(
                nameof(property.ValueAccessor),
                BindingMode.TwoWay);
            ctrlTextBox.Width      = double.NaN;
            ctrlTextBox.IsReadOnly = property.IsReadOnly;

            if (null != property.GetCustomAttribute <LinkAttribute>())
            {
                ctrlTextBox.Classes.Add("Link");
                ctrlTextBox.IsReadOnly       = true;
                ctrlTextBox.Cursor           = new Cursor(StandardCursorType.Hand);
                ctrlTextBox.PointerReleased += (sender, args) =>
                {
                    CommonUtil.OpenUrlInBrowser(ctrlTextBox.Text);
                };
            }

            return(ctrlTextBox);
        }
        protected virtual Control CreateFixedPossibleValuesControl(
            ConfigurablePropertyMetadata property,
            IEnumerable <ConfigurablePropertyMetadata> allProperties)
        {
            var ctrlComboBox = new ComboBox();

            var possibleValueAttrib = property.GetCustomAttribute <FixedPossibleValuesAttribute>();

            if (possibleValueAttrib != null)
            {
                var getValuesMethod = property.HostObjectType.GetMethod(
                    possibleValueAttrib.ValueGetterMethodName,
                    BindingFlags.Static | BindingFlags.Public);
                if ((getValuesMethod != null) &&
                    (getValuesMethod.Invoke(null, null) is IEnumerable collection))
                {
                    ctrlComboBox.Items = collection;
                }
            }

            ctrlComboBox[!SelectingItemsControl.SelectedItemProperty] = new Binding(
                nameof(property.ValueAccessor),
                BindingMode.TwoWay);
            ctrlComboBox.Width     = double.NaN;
            ctrlComboBox.IsEnabled = !property.IsReadOnly;

            return(ctrlComboBox);
        }
        protected virtual Control CreateTextAndHexadecimalEditControl(
            ConfigurablePropertyMetadata property,
            IEnumerable <ConfigurablePropertyMetadata> allProperties)
        {
            var otherPropertyInfo = property.GetCustomAttribute <TextAndHexadecimalEditAttribute>();

            if (otherPropertyInfo == null)
            {
                throw new InvalidOperationException($"{nameof(TextAndHexadecimalEditAttribute)} not found on property {property.PropertyName}!");
            }

            var otherProperty = allProperties
                                .FirstOrDefault(actProperty => actProperty.PropertyName == otherPropertyInfo.EncodingWebNamePropertyName);

            if (otherProperty == null)
            {
                throw new InvalidOperationException($"Property {otherPropertyInfo.EncodingWebNamePropertyName} not found!");
            }

            var stackPanel = new StackPanel();

            stackPanel.Orientation = Orientation.Vertical;

            var ctrlTextBox1 = new TextBox();

            ctrlTextBox1[!TextBox.TextProperty] = new Binding(
                nameof(property.ValueAccessor),
                BindingMode.TwoWay);
            ctrlTextBox1.Width      = double.NaN;
            ctrlTextBox1.IsReadOnly = property.IsReadOnly;

            var hexTextBinding = new Binding(
                nameof(property.ValueAccessor),
                BindingMode.TwoWay)
            {
                Converter          = new TextToHexConverter(),
                ConverterParameter = new Func <string?>(() => otherProperty.ValueAccessor as string)
            };

            var ctrlTextBox2Container = new Grid();

            ctrlTextBox2Container.ColumnDefinitions.Add(new ColumnDefinition(GridLength.Auto));
            ctrlTextBox2Container.ColumnDefinitions.Add(new ColumnDefinition(GridLength.Parse("*")));

            var ctrlTextBox2Header = new TextBlock();

            ctrlTextBox2Header.Text = "HEX";
            ctrlTextBox2Header.SetValue(Grid.ColumnProperty, 0);
            ctrlTextBox2Container.Children.Add(ctrlTextBox2Header);

            var ctrlTextBox2 = new TextBox();

            ctrlTextBox2[!TextBox.TextProperty] = hexTextBinding;
            ctrlTextBox2.Width      = double.NaN;
            ctrlTextBox2.IsReadOnly = property.IsReadOnly;

            otherProperty.RegisterWeakPropertyChangedTarget(
                new WeakReference(ctrlTextBox2),
                (sender, eArgs) =>
            {
                ctrlTextBox2[!TextBox.TextProperty] = hexTextBinding;
            });

            ctrlTextBox2.SetValue(Grid.ColumnProperty, 1);
            ctrlTextBox2Container.Children.Add(ctrlTextBox2);

            stackPanel.Children.Add(ctrlTextBox1);
            stackPanel.Children.Add(ctrlTextBox2Container);

            return(stackPanel);
        }