A
A
Alexey2016-11-19 11:21:12
WPF
Alexey, 2016-11-19 11:21:12

How to set up receiving additional properties when using "your" control?

I needed it in a TextBox project with a title.
Without hesitation, with the help of the Internet, having peeped a bit of someone else's code, I made a component for myself:
Source code:

public class KeyValueControl : Control
    {
        public static readonly DependencyProperty KeyProperty = DependencyProperty.Register(
            "Key",
            typeof(string),
            typeof(KeyValueControl),
            new PropertyMetadata(default(string)));

        public static readonly DependencyProperty ValueProperty = DependencyProperty.Register(
            "Value",
            typeof(object),
            typeof(KeyValueControl),
            new FrameworkPropertyMetadata
            {
                DefaultValue = null,
                BindsTwoWayByDefault = true,
                DefaultUpdateSourceTrigger = UpdateSourceTrigger.PropertyChanged,
            });

        static KeyValueControl()
        {
            DefaultStyleKeyProperty.OverrideMetadata(typeof(KeyValueControl), new FrameworkPropertyMetadata(typeof(KeyValueControl)));
        }

        public string Key
        {
            get
            {
                return (string)GetValue(KeyProperty);
            }
            set
            {
                SetValue(KeyProperty, value);
            }
        }

        public object Value
        {
            get
            {
                return GetValue(ValueProperty);
            }
            set
            {
                SetValue(ValueProperty, value);
            }
        }
    }

XAML:
<Style TargetType="{x:Type myctrl:KeyValueControl}">
            <Setter Property="Template">
                <Setter.Value>
                    <ControlTemplate TargetType="{x:Type myctrl:KeyValueControl}">
                        <Border Margin="2"
                                BorderBrush="DarkBlue"
                                BorderThickness="2"
                                CornerRadius="2"
                                Padding="2">
                            <Grid>
                                <Grid.RowDefinitions>
                                    <RowDefinition />
                                    <RowDefinition />
                                </Grid.RowDefinitions>
                                <TextBlock Text="{Binding Key, RelativeSource={RelativeSource TemplatedParent}}" />
                                <TextBox Grid.Row="1"
                                         IsReadOnly="True"
                                         Text="{Binding Value, 
                                                        RelativeSource={RelativeSource TemplatedParent},
                                                        UpdateSourceTrigger=PropertyChanged}"
                                         />
                            </Grid>
                        </Border>
                    </ControlTemplate>
                </Setter.Value>
            </Setter>
        </Style>

As a result, several of these components look like this:
610771fa47e4477d9332e8ac1041a0cc.png
And everything seems to be fine, with a couple of exceptions:
1. No matter how hard I try to specify the StringFormat property for the component, the TextBox still does not reach.
<myctrl:KeyValueControl Key="Цена продажи" Value="{Binding SellPrice, Mode=OneWay, StringFormat=F2}" />

d078ada134f94e1ea36eb8bc47462ed6.png
2. How can I make a custom IsReadOnly property for this component? So far, I have hardcoded it in the style, but I would like to have something like:
<myctrl:KeyValueControl Key="Цена продажи" Value="{Binding SellPrice, Mode=OneWay, StringFormat=F2}"   IsReadOnly="True" />

Help me to understand. Thanks in advance.

Answer the question

In order to leave comments, you need to log in

1 answer(s)
A
Alexey, 2016-11-19
@k1lex

I still found the answer to part of the question on my own.
The StringFormat was not picked up because when the DependencyProperty was created, the "Value" property was of type object. And StringFormat is only used for the String type. In view of the fact that I need this component only for reading, I changed typeof (object) to typeof (string) and everything began to work as it should.
Of course, this is not a normal solution. But as one hero said in the good old cartoon: "And so it will do"
More details about this are written on stackoverflow
As for isReadOnly - I added one more property for the component, similar to the first two (value and key). Works.

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question