#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. Большое спасибо. Я не должен был понимать это самостоятельно, но, конечно, это было так.