我有 3 个列表框都绑定了两个相同类型的 3 个单独的可观察集合。我的 ViewModel 具有通过属性公开的可观察集合。这是一些拖放分组,源列表框可以将项目拖到两个不同的列表中。但我想让用户能够右键单击列表框并设置项目的属性。类型、名称等。我在其中使用数据模板,因为我希望所有三个框在功能上都相同。这很好用,当我单击单个项目时,我可以毫无问题地弹出上下文菜单。我的麻烦是我有一个名为 FieldType 的属性。它是一个具有 4 个潜在值的枚举。在我的一生中,我无法弄清楚如何将 MenuItem 的 IsChecked 属性绑定到该属性......无论如何在功能上。
<DataTemplate x:Key="SFTemplateWithContextMenu">
<TextBlock Text="{Binding Path=FieldName}" ><!--Tag="{Binding DataContext, ElementName=Window}"-->
<TextBlock.ContextMenu>
<ContextMenu >
<ContextMenu.Resources>
<Configurator:EnumToBooleanConverter x:Key="EnumToBooleanConverterc" />
</ContextMenu.Resources>
<MenuItem Header="Rename..." />
<MenuItem Header="Field Type">
<MenuItem.Resources>
<Configurator:EnumToBooleanConverter x:Key="EnumToBooleanConverter" />
</MenuItem.Resources>
<MenuItem Header="String" IsCheckable="True" IsChecked="{Binding RelativeSource={RelativeSource AncestorType={x:Type ContextMenu}}, Path=DataContext.FieldType, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged, Converter={StaticResource EnumToBooleanConverterc}, ConverterParameter={x:Static Configurator:TypeDesc.String}, PresentationTraceSources.TraceLevel=High}"/>
<MenuItem Header="Date" IsCheckable="True" IsChecked="{Binding RelativeSource={RelativeSource AncestorType={x:Type ContextMenu}}, Path=DataContext.FieldType, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged, Converter={StaticResource EnumToBooleanConverter}, ConverterParameter={x:Static Configurator:TypeDesc.Date}}"/>
<MenuItem Header="Barcode" IsCheckable="True" IsChecked="{Binding RelativeSource={RelativeSource AncestorType={x:Type ContextMenu}}, Path=DataContext.FieldType, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged, Converter={StaticResource EnumToBooleanConverter}, ConverterParameter={x:Static Configurator:TypeDesc.BarCode}}" />
</MenuItem>
</ContextMenu>
</TextBlock.ContextMenu>
</TextBlock>
</DataTemplate>
在上面的代码中,您可以在 String、Date 和 Barcode MenuItems 上看到我正在尝试做的事情(必须喜欢正在进行中的代码)。我的问题是它应该调用的暴露属性。我不知道如何在我的 ViewModel 属性中获取与单击的项目相对应的可观察集合中的项目。我有一个值转换器 EnumToBoolean 将位于绑定上以获取检查或不检查。问题是在可观察集合中设置/获取该特定项目的属性。
有什么想法吗?需要更多代码?需要我澄清什么吗?我离我有多近?顺便说一句,ViewModel 代码是用 VB 2010 编写的。
谢谢布莱斯
编辑:我使用天使的建议尝试了以下...
<DataTemplate x:Key="SFTemplateWithContextMenu">
<TextBlock x:Name="Field" Text="{Binding Path=FieldName}" >
<TextBlock.ContextMenu PlacementTarget="{Binding ElementName=Field}">
<MenuItem Header="Rename..." />
<MenuItem Header="Field Type">
<MenuItem.Resources>
<Configurator:EnumToBooleanConverter x:Key="EnumToBooleanConverter" />
</MenuItem.Resources>
<MenuItem Header="Date" IsCheckable="True" IsChecked="{Binding PlacementTarget.DataContext.FieldType, RelativeSource={RelativeSource AncestorType={x:Type ContextMenu}}, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged, Converter={StaticResource EnumToBooleanConverter}, ConverterParameter={x:Static Configurator:TypeDesc.String}, PresentationTraceSources.TraceLevel=High}"/>
</MenuItem>
</TextBlock.ContextMenu>
</TextBlock>
</DataTemplate>
但这给了我一个错误,上面写着......无法在属性元素上设置属性。不确定这是否是 TextBlox 与 TextBox 的问题?您在示例中使用了 TextBox ...我的猜测是您的代码也会这样做。所以我然后尝试了以下...
<DataTemplate x:Key="SFTemplateWithContextMenu">
<TextBlock x:Name="Field" Text="{Binding Path=FieldName}" ><!--Tag="{Binding DataContext, ElementName=Window}"-->
<TextBlock.ContextMenu>
<ContextMenu PlacementTarget="{Binding ElementName=Field}" >
<MenuItem Header="Rename..." />
<MenuItem Header="Field Type">
<MenuItem.Resources>
<Configurator:EnumToBooleanConverter x:Key="EnumToBooleanConverter" />
</MenuItem.Resources>
<MenuItem Header="Date" IsCheckable="True" IsChecked="{Binding PlacementTarget.DataContext.FieldType, RelativeSource={RelativeSource AncestorType={x:Type ContextMenu}}, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged, Converter={StaticResource EnumToBooleanConverter}, ConverterParameter={x:Static Configurator:TypeDesc.String}, PresentationTraceSources.TraceLevel=High}"/>
</MenuItem>
</ContextMenu>
</TextBlock.ContextMenu>
</TextBlock>
</DataTemplate>
但这会导致绑定错误... System.Windows.Data 错误:4:无法使用引用“ElementName = Field”找到绑定源。BindingExpression:(无路径);数据项=空;目标元素是'ContextMenu'(名称='');目标属性是“PlacementTarget”(类型“UIElement”)
所以看起来绑定不起作用。有什么想法吗?