k1lex
@k1lex
Программист торг. сети. C# (WPF, WinForms), T-SQL

Как настроить получение дополнительных свойств при использовании «своего» контрола?

Понадобился мне в проекте TextBox c заголовком.
Не долго думая, с помощью интернета, подсмотрев немного чужого кода, изготовил себе компонент:

Исходный код:
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>

В итоге несколько таких компонентов выглядят вот так:
610771fa47e4477d9332e8ac1041a0cc.png

И вроде бы всё хорошо, за парой исключений:
1. Как бы я не старался указать для компонента свойтво StringFormat , до TextBox всё равно не доходит.
<myctrl:KeyValueControl Key="Цена продажи" Value="{Binding SellPrice, Mode=OneWay, StringFormat=F2}" />

d078ada134f94e1ea36eb8bc47462ed6.png
2. Как сделать для этого компонента настраиваемое свойство IsReadOnly ? Пока я жестко прописал его в стиле, а хотелось бы иметь что-то вида:
<myctrl:KeyValueControl Key="Цена продажи" Value="{Binding SellPrice, Mode=OneWay, StringFormat=F2}"   IsReadOnly="True" />

Помогите разобраться. Заранее спасибо.
  • Вопрос задан
  • 129 просмотров
Пригласить эксперта
Ответы на вопрос 1
k1lex
@k1lex Автор вопроса
Программист торг. сети. C# (WPF, WinForms), T-SQL
На часть вопроса я всё таки нашел ответ самостоятельно.
StringFormat не подхватывался, потому что при создании DependencyProperty у свойства "Value" использовался тип object. А StringFormat используется только для типа String. В виду того, что этот компонент нужен мне только для чтения, я поменял typeof(object) на typeof(string) и всё стало работать как нужно.
Нормальным решением это конечно не назовешь. Но как говорил один герой в старом и добром мультфильме: "И так сойдет"
Более подробно об этом написано на stackoverflow

Насчет isReadOnly - завел для компонента еще одно свойство, аналогично первым двум (value и key). Работает.
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы