I am using Mahapps.Metro.Controls.DropDownButton
in a UserControl
in my project, which I populate using data binding. In order to know which item gets selected, I apply an item template in which I specify the item click handler. The relevant XAML is
<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>
The DataContext
is a custom view model set in the constructor in the code-behind for the user control:
public CatalogueEditor()
{
InitializeComponent();
this.viewModel = new CatalogueEditorViewModel();
this.DataContext = this.viewModel;
}
The Catalogues
property in the view model is a custom KeyedCollection<string, Catalogue>
that implements INotifyCollectionChanged
. This contains elements that are similar custom KeyedCollection
objects implementing INotifyCollectionChanged
, but with item type Question
, which is no longer a collection. Catalogue
objects have a read-only property Id
, to which I bind the TextBlock
in the item template.
The binding seems to work all right and the DropDownButton
gets populated with the Id
labels of the Catalogue
objects in the Catalogues
collection, yet I get an output informing me of a binding error:
System.Windows.Data Error: 40 : BindingExpression path error: 'Id' property not found on 'object' ''String' (HashCode=-842352768)'. BindingExpression:Path=Id; DataItem='String' (HashCode=-842352768); target element is 'TextBlock' (Name=''); target property is 'Text' (type 'String')
This tells me that at some point the DataContext
of the TextBlock
in the item template is perceived as a String
, though I intend it to be a Catalogue
as an item in the collection bound to the ItemsSource
. It is not only the correct operation that corroborates this notion but also my HandleDropDownItemMouseDown
event handler:
void HandleDropDownItemMouseDown(object sender, MouseButtonEventArgs e)
{
if (e.ChangedButton == MouseButton.Left && selector.IsExpanded) {
Catalogue catalogue = ((TextBlock)e.Source).DataContext as Catalogue;
if (catalogue != null) {
viewModel.Select(catalogue);
}
}
}
Placing a breakpoint here I can see that the DataContext
of the TextBlock
is indeed a Catalogue
and the code works as intended.
Why does this apparent error message occur? Shall I worry about it, does it signify that I made some insidious mistake in my code, or shall I be content that the code works? My apologies if this is an irrelevant or stupid question, but I am just learning WPF and I find it quite challenging, so I try to understand what happens around me even if my code happens to work. Your insights are much appreciated.
The offending line is Content=" "
. You are setting content of a control to " "
string, to which control tries to apply your template. As string
class has no Id
property, it results in a binding error.