Привязка WPF в ItemTemplate работает, но выдает сообщения об ошибках

#c# #wpf #binding #itemtemplate #itemssource

#c# #wpf #привязка #itemtemplate #itemssource

Вопрос:

Я использую Mahapps.Metro.Controls.DropDownButton in a UserControl в своем проекте, который я заполняю с помощью привязки данных. Чтобы узнать, какой элемент будет выбран, я применяю шаблон элемента, в котором я указываю обработчик щелчка элемента. Соответствующий XAML

 <Controls:DropDownButton
    x:Name="selector"
    VerticalContentAlignment="Center"
    Content=" "
    Background="Transparent"
    BorderThickness="0"
    ItemsSource="{Binding Catalogues}"
>
   <Controls:DropDownButton.ItemTemplate>
      <DataTemplate>
         <TextBlock Text="{Binding Id}" MouseDown="HandleDropDownItemMouseDown" />
      </DataTemplate>
   </Controls:DropDownButton.ItemTemplate>
</Controls:DropDownButton>
  

Это DataContext пользовательская модель представления, установленная в конструкторе в коде для пользовательского элемента управления:

 public CatalogueEditor()
{
        InitializeComponent();

        this.viewModel = new CatalogueEditorViewModel();
        this.DataContext = this.viewModel;
}
  

Catalogues Свойство в модели представления является пользовательским KeyedCollection<string, Catalogue> , которое реализует INotifyCollectionChanged . Это содержит элементы, которые являются аналогичными пользовательскими KeyedCollection объектами, реализующими INotifyCollectionChanged , но с типом элемента Question , который больше не является коллекцией. Catalogue объекты имеют свойство только для чтения Id , к которому я привязываю TextBlock шаблон элемента.

Привязка, похоже, работает нормально, и DropDownButton она заполняется Id метками Catalogue объектов в Catalogues коллекции, но я получаю вывод, информирующий меня об ошибке привязки:

Система.Windows.Ошибка данных: 40: ошибка пути к BindingExpression: свойство ‘Id’ не найдено в ‘object’ ‘String’ (hashCode =-842352768)’. Выражение привязки: Path=Id; DataItem=’String’ (hashCode =-842352768); целевой элемент — ‘TextBlock’ (Name=»); целевое свойство — ‘Text’ (тип ‘String’)

Это говорит мне о том, что в какой-то момент DataContext элемент TextBlock в шаблоне элемента воспринимается как a String , хотя я предполагаю, что это будет a Catalogue как элемент в коллекции, привязанный к ItemsSource . Это подтверждает не только правильная операция, но и мой HandleDropDownItemMouseDown обработчик событий:

 void HandleDropDownItemMouseDown(object sender, MouseButtonEventArgs e)
{
        if (e.ChangedButton == MouseButton.Left amp;amp; selector.IsExpanded) {
            Catalogue catalogue = ((TextBlock)e.Source).DataContext as Catalogue;

            if (catalogue != null) {
                viewModel.Select(catalogue);
            }
        }
}
  

Установив здесь точку останова, я вижу, что DataContext из TextBlock действительно a Catalogue и код работает так, как задумано.

Почему возникает это очевидное сообщение об ошибке? Должен ли я беспокоиться об этом, означает ли это, что я допустил какую-то коварную ошибку в своем коде, или я должен быть доволен тем, что код работает? Приношу свои извинения, если это неуместный или глупый вопрос, но я только изучаю WPF и нахожу его довольно сложным, поэтому я пытаюсь понять, что происходит вокруг меня, даже если мой код работает. Ваши идеи очень ценятся.

Ответ №1:

Нарушающая строка Content=" " . Вы устанавливаете содержимое элемента управления в " " строку, к которой элемент управления пытается применить ваш шаблон. Поскольку string класс не имеет Id свойства, это приводит к ошибке привязки.

Комментарии:

1. Большое спасибо. Я не должен был понимать это самостоятельно, но, конечно, это было так.