ObservableCollection имеет значение Null, когда я пытаюсь добавить TextBlocks через XAML в пользовательский элемент управления - PullRequest
0 голосов
/ 24 декабря 2018

В моем проекте WPF я пытаюсь создать свойство зависимости ObservalbeCollection внутри пользовательского элемента управления.Я не уверен, правильно ли я делаю это, но я использую следующий код:

public static readonly DependencyProperty MenuOptionsDependency = DependencyProperty.Register("MenuOptions", typeof(ObservableCollection<TextBlock>), typeof(DropDownButton));


public ObservableCollection<TextBlock> MenuOptions
 {
    get
    {
      return (ObservableCollection<TextBlock>)GetValue(MenuOptionsDependency);
    }
     set
    {
     SetValue(MenuOptionsDependency, value);
    }
 }

Проблема возникает, когда я пытаюсь добавить TextBlock s через XAML к этому элементу управления следующим образом:

<local:CustomControl1 x:Name="cmm">
  <local:CustomControl1.MenuOptions>
   <TextBlock/>
  </local:CustomControl1.MenuOptions>
</local:CustomControl1>

Это выдает ошибку времени проектирования, говоря:

Коллекция 'CustomControl1'. 'MenuOptions' имеет значение null

После прохождения принятого ответа этот пост SO , я понимаю, ObservableCollection, будучи ссылочным типом, будет null, поскольку будет значением по умолчанию.Я прочитал ответ, но до сих пор неясно / не уверен, как реализовать решение в моей ситуации.

Мне нужно иметь возможность добавлять объекты в коллекцию через XAML (а также через C #).Я был бы очень признателен, если бы кто-то указал, где я пропускаю / что я делаю неправильно.

1 Ответ

0 голосов
/ 24 декабря 2018

Вы никогда не должны устанавливать значение по умолчанию для свойства зависимости типа коллекции в значение, отличное от null.Когда вы назначаете ненулевое значение по умолчанию с помощью (статических) метаданных свойства, все экземпляры вашего элемента управления будут использовать один и тот же объект коллекции.

Вместо этого установите значение по умолчанию в конструкторе элемента управления с помощью SetCurrentValue:

public DropDownButton()
{
    SetCurrentValue(MenuOptionsDependency, new ObservableCollection<TextBlock>());
}

Кроме того, существует строгое соглашение об именах, согласно которому поле идентификатора свойства зависимости должно быть названо как свойство с суффиксом Property.Таким образом, ваш MenuOptionsDependency должен на самом деле называться MenuOptionsProperty.

Также неясно, должен ли тип свойства действительно быть ObservableCollection.Похоже, вы нигде не регистрируете обработчик событий CollectionChanged, что указывает на то, что ваш элемент управления не должен реагировать на такие изменения.

Рассмотрим объявление свойства следующим образом:

public DropDownButton()
{
    SetCurrentValue(MenuOptionsProperty, new List<TextBlock>());
}

public static readonly DependencyProperty MenuOptionsProperty =
    DependencyProperty.Register(
        nameof(MenuOptions), typeof(IEnumerable<TextBlock>), typeof(DropDownButton));

public IEnumerable<TextBlock> MenuOptions
{
    get { return (IEnumerable<TextBlock>)GetValue(MenuOptionsProperty); }
    set { SetValue(MenuOptionsProperty, value); }
}
...