My application consists of Categories that contain many Products.
Given a Category, I want to display an element for each of its Products:
<UserControl x:Class="MyApp.CategoryControl"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:MyApp"
>
<StackPanel>
<TextBlock>Products:</TextBlock>
<ItemsControl ItemsSource="{Binding Path=Products}">
<ItemsControl.ItemTemplate>
<DataTemplate>
<local:ProductControl Product="{Binding}" />
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</StackPanel>
</UserControl>
public partial class CategoryControl : UserControl
{
public Product[] Products { get; set; }
}
...wherein it displays some information about the Product, and shows/collapses additional information when the Product name is clicked:
<UserControl x:Class="MyApp.ProductControl"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:MyApp"
>
<StackPanel>
<TextBlock MouseDown="ProductName_Click" Text="{Binding Path=Product.Name}" />
<TextBlock
Text="{Binding Path=Product.Description}"
Visibility="{Binding Path=IsCollapsed, Converter={local:BooleanToVisiblity}}"
/>
</StackPanel>
</UserControl>
public partial class ProductControl : UserControl
{
public bool IsCollapsed { get; set; } = true;
public Product Product
{
get => (Product)GetValue(ProductProperty);
set => SetValue(ProductProperty, value);
}
public static readonly DependencyProperty ProductProperty = DependencyProperty.Register(
"Product",
typeof(Product),
typeof(FrameworkElement)
);
public ProductControl ()
{
DataContext = this;
InitializeComponent();
}
public void ProductName_Click(object sender, EventArgs e) {
IsCollapsed = !IsCollapsed;
PropertyChanged("IsCollapsed");
}
}
However this produces the following two errors, once each per Product:
System.Windows.Data Error: 1 : Cannot create default converter to perform 'one-way' conversions between types 'MyApp.ProductControl' and 'MyApp.Product'. Consider using Converter property of Binding. BindingExpression:Path=; DataItem='ProductControl' (Name=''); target element is 'ProductControl' (Name=''); target property is 'Product' (type 'Product')
System.Windows.Data Error: 5 : Value produced by BindingExpression is not valid for target property.; Value='MyApp.ProductControl' BindingExpression:Path=; DataItem='ProductControl' (Name=''); target element is 'ProductControl' (Name=''); target property is 'Product' (type 'Product')
What am I doing wrong?