Свойство зависимости пользовательского элемента управления WPF не является обязательным - PullRequest
2 голосов
/ 11 марта 2019

Я знаю, что есть много похожих вопросов, я прочитал их за последний день или около того, но ни одно из решений не помогло мне.

У меня есть пользовательский элемент управления WPF, который в основномсупепед ComboBox, на котором я хотел бы включить привязку данных.Я следовал коду, показанному в принятом ответе на этот вопрос SO , но привязка не работает.

Урезанная версия содержимого пользовательского элемента управления выглядит следующим образом...

<UserControl x:Class="Sample.MyComboBox"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
    <ComboBox Name="EntityTb"
              IsEditable="True" />
</UserControl>

Очевидно, что это намного больше, но остальное не имеет отношения к моему вопросу.

В коде позади я добавил свойство зависимости, называемое Text следующим образом ...

public static readonly DependencyProperty TextProperty
         = DependencyProperty.Register("Text", typeof(string),
  typeof(MyComboBox), new FrameworkPropertyMetadata() {
    BindsTwoWayByDefault = true,
    PropertyChangedCallback = TextChanged,
    DefaultUpdateSourceTrigger = UpdateSourceTrigger.PropertyChanged
  });


private static void TextChanged(DependencyObject d,
                             DependencyPropertyChangedEventArgs e) {
  MyComboBox cmb = (MyComboBox)d;
  cmb.EntityTb.Text = e.NewValue.ToString();
}

public string Text {
  get => (string)GetValue(TextProperty);
  set => SetValue(TextProperty, value);
}

Затем я попытался использовать это в окне WPF.Модель представления имеет свойство Customer, которое имеет свойство Name, которое я хочу связать с пользовательским элементом управления ...

<controls:MyComboBox Grid.Column="1"
     Text="{Binding Customer.Name, Mode=TwoWay}" />

Свойство Customer не является более сложным, чем ...

private Customer _customer;

public Customer Customer {
  get => _customer;
  set {
    if (_customer != value) {
      _customer = value;
      RaisePropertyChanged();
    }
  }
}

... и сам тип Customer является просто классом C # ...

public partial class Customer {
  public string Name { get; set; }
}

Однако ничего не происходит.Когда окно загружается, имя клиента не отображается в поле со списком, и если я что-то там набираю, модель не обновляется.

Я провел большой поиск, и, похоже, все примеры кодапохож на тот, что выше.Кто-нибудь может сказать мне, что я делаю неправильно?

1 Ответ

1 голос
/ 12 марта 2019

Обновление cmb.EntityTb.Text в PropertyChangedCallback работает только в одном направлении.

Вместо этого используйте двустороннюю привязку, например

<ComboBox IsEditable="True"
    Text="{Binding Text, RelativeSource={RelativeSource AncestorType=UserControl}}"/>

Поскольку свойство ComboBox.Text по умолчанию также привязывает двустороннюю привязку, установка Mode=TwoWay является избыточной.

...