Caliburn Micro在ListView的ContextMenu中找不到DataContext
本文关键字:找不到 DataContext ContextMenu Micro ListView Caliburn | 更新日期: 2023-09-27 18:12:08
我已经用对象填充了一个ListView,并且我已经将一个ContextMenu绑定到我的ListView中的那些项目。ContextMenu只能通过单击某一项来打开。问题是Caliburn Micro抛出了一个错误,它无法找到ShowProperties()的目标方法。
我认为这个问题的发生是因为Caliburn没有正确的DataContext的ViewModel可用。我在Stackoverflow上尝试了许多解决方案,使ViewModel可用于ContextMenu项,但无济于事,例如:
WPF:将ContextMenu绑定到MVVM命令
Caliburn Message.Attach()抛出" No target found for method "
Caliburn Micro中的WPF上下文菜单
这是我的视图的XAML代码:
<Window x:Class="CueMaster.Views.AppView"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:dragDrop="clr-namespace:GongSolutions.Wpf.DragDrop;assembly=GongSolutions.Wpf.DragDrop"
xmlns:cal="http://www.caliburnproject.org"
Height="500" Width="800">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="200" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<ListView Grid.Column="1" Margin="5"
ItemsSource="{Binding Cues}"
dragDrop:DragDrop.IsDragSource="True"
dragDrop:DragDrop.IsDropTarget="True"
dragDrop:DragDrop.DropHandler="{Binding}">
<ListView.Resources>
<ContextMenu x:Key="ItemContextMenu">
<MenuItem Header="Properties" cal:Message.Attach="ShowProperties($dataContext)" Command="{Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=ListView}}">
<MenuItem.Icon>
<Image Source="../PropertyIcon.png" />
</MenuItem.Icon>
</MenuItem>
</ContextMenu>
</ListView.Resources>
<ListView.ItemContainerStyle>
<Style TargetType="{x:Type ListViewItem}" >
<Setter Property="ContextMenu" Value="{StaticResource ItemContextMenu}" />
</Style>
</ListView.ItemContainerStyle>
<ListView.View>
<GridView >
<GridViewColumn Width="70" Header="Cue" DisplayMemberBinding="{Binding Id}" />
<GridViewColumn Width="100" Header="Name" DisplayMemberBinding="{Binding Name}" />
<GridViewColumn Width="100" Header="Description" DisplayMemberBinding="{Binding Description}" />
<GridViewColumn Width="70" Header="Duration" DisplayMemberBinding="{Binding Duration}" />
<GridViewColumn Width="70" Header="Elapsed" DisplayMemberBinding="{Binding Elapsed}" />
<GridViewColumn Width="70" Header="Remaining" DisplayMemberBinding="{Binding Remaining}" />
</GridView>
</ListView.View>
</ListView>
</Grid>
我错过了什么?
您通过放置Command绑定来覆盖CM将要做的事情。因为可视化树不知道上下文菜单的存在,更不用说背后的数据上下文了。
<ListView.ItemContainerStyle>
<Style TargetType="{x:Type ListViewItem}">
<Setter Property="Tag" Value="{Binding Path=DataContext, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=ListView}}"/>
<Setter Property="ContextMenu">
<Setter.Value>
<ContextMenu cal:Action.TargetWithoutContext="{Binding Path=PlacementTarget.Tag, RelativeSource={RelativeSource Self}}">
<MenuItem Header="Properties" cal:Message.Attach="ShowProperties($dataContext)" >
<MenuItem.Icon>
<Image Source="../PropertyIcon.png" />
</MenuItem.Icon>
</MenuItem>
</ContextMenu>
</Setter.Value>
</Setter>
</Style>
</ListView.ItemContainerStyle>
虽然我理解您试图在ListView中使用资源做什么,但您正在用命令绑定射击自己的脚。放下资源,给ItemContainerStyle一个滚动,看看它是否工作。您可以稍后将其拆分为一个资源。为了测试它是否工作,现在尝试内部样式。
使用mvermef的答案,我让它工作。在他的代码中唯一需要更改的是绑定意味着"沿着Visual Tree向上移动,找到该对象上方的第一个ContextMenu对象,并绑定到PlacementTarget。"标签属性"。问题是绑定是在ContextMenu本身上,所以没有父ContextMenu对象。使用RelativeSource Self修复了这个问题。
<ListView.ItemContainerStyle>
<Style TargetType="{x:Type ListViewItem}">
<Setter Property="Tag" Value="{Binding Path=DataContext, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=ListView}}"/>
<Setter Property="ContextMenu">
<Setter.Value>
<ContextMenu cal:Action.TargetWithoutContext="{Binding Path=PlacementTarget.Tag, RelativeSource={RelativeSource Self}}">
<MenuItem Header="Properties" cal:Message.Attach="ShowProperties($dataContext)" >
<MenuItem.Icon>
<Image Source="../PropertyIcon.png" />
</MenuItem.Icon>
</MenuItem>
</ContextMenu>
</Setter.Value>
</Setter>
</Style>
</ListView.ItemContainerStyle>