ItemTemplate 中的 WPF 绑定有效但会产生错误消息
WPF binding in ItemTemplate works but produces error messages
我在我的项目的 UserControl
中使用 Mahapps.Metro.Controls.DropDownButton
,我使用数据绑定填充它。为了知道选择了哪个项目,我应用了一个项目模板,我在其中指定了项目点击处理程序。相关的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
属性是实现INotifyCollectionChanged
的自定义KeyedCollection<string, Catalogue>
。这包含类似于实现 INotifyCollectionChanged
的自定义 KeyedCollection
对象的元素,但项目类型 Question
,不再是集合。 Catalogue
对象有一个只读的 属性 Id
,我在项目模板中将 TextBlock
绑定到它。
绑定似乎工作正常,DropDownButton
填充了 Catalogues
集合中 Catalogue
对象的 Id
标签,但我得到了一个通知我绑定错误的输出:
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')
这告诉我,在某些时候,项目模板中 TextBlock
的 DataContext
被视为 String
,尽管我打算将其视为 Catalogue
作为绑定到 ItemsSource
的集合中的一项。不仅是正确的操作证实了这个观点,而且我的 HandleDropDownItemMouseDown
事件处理程序也是如此:
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);
}
}
}
在这里放置一个断点我可以看到 TextBlock
的 DataContext
确实是 Catalogue
并且代码按预期工作。
为什么会出现这个明显的错误消息?我应该担心吗,这是否意味着我在我的代码中犯了一些潜在的错误,或者我应该满足于代码的工作?如果这是一个不相关或愚蠢的问题,我深表歉意,但我只是在学习 WPF,我发现它非常具有挑战性,所以即使我的代码恰好可以工作,我也会尝试了解我周围发生的事情。非常感谢您的见解。
违规行是Content=" "
。您正在将控件的内容设置为 " "
字符串,控件尝试将您的模板应用到该字符串。由于 string
class 没有 Id
属性,因此会导致绑定错误。
我在我的项目的 UserControl
中使用 Mahapps.Metro.Controls.DropDownButton
,我使用数据绑定填充它。为了知道选择了哪个项目,我应用了一个项目模板,我在其中指定了项目点击处理程序。相关的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
属性是实现INotifyCollectionChanged
的自定义KeyedCollection<string, Catalogue>
。这包含类似于实现 INotifyCollectionChanged
的自定义 KeyedCollection
对象的元素,但项目类型 Question
,不再是集合。 Catalogue
对象有一个只读的 属性 Id
,我在项目模板中将 TextBlock
绑定到它。
绑定似乎工作正常,DropDownButton
填充了 Catalogues
集合中 Catalogue
对象的 Id
标签,但我得到了一个通知我绑定错误的输出:
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')
这告诉我,在某些时候,项目模板中 TextBlock
的 DataContext
被视为 String
,尽管我打算将其视为 Catalogue
作为绑定到 ItemsSource
的集合中的一项。不仅是正确的操作证实了这个观点,而且我的 HandleDropDownItemMouseDown
事件处理程序也是如此:
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);
}
}
}
在这里放置一个断点我可以看到 TextBlock
的 DataContext
确实是 Catalogue
并且代码按预期工作。
为什么会出现这个明显的错误消息?我应该担心吗,这是否意味着我在我的代码中犯了一些潜在的错误,或者我应该满足于代码的工作?如果这是一个不相关或愚蠢的问题,我深表歉意,但我只是在学习 WPF,我发现它非常具有挑战性,所以即使我的代码恰好可以工作,我也会尝试了解我周围发生的事情。非常感谢您的见解。
违规行是Content=" "
。您正在将控件的内容设置为 " "
字符串,控件尝试将您的模板应用到该字符串。由于 string
class 没有 Id
属性,因此会导致绑定错误。