WPF 编程打开ListViewItem的ContextMenu丢失DataContext问题
问题根因
ContextMenu属于WPF的弹出层控件,不在主可视化树中,仅当通过右键点击触发打开时,WPF会自动将ContextMenu的PlacementTarget属性设置为被点击的ListViewItem,此时内部命令绑定可以正常继承ListViewItem的DataContext。你通过ToggleButton绑定手动设置IsOpen=true时,系统不会自动赋值PlacementTarget,导致ContextMenu找不到绑定源,命令失效。
可行解决方案
直接在ContextMenu声明中显式绑定DataContext与PlacementTarget即可,无需修改其他逻辑,修改后的代码如下:
<ListView> <ListView.ItemContainerStyle> <Style TargetType="{x:Type ListViewItem}"> <Setter Property="ContextMenu"> <Setter.Value> <!-- 新增PlacementTarget和DataContext绑定 --> <ContextMenu PlacementTarget="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type ListViewItem}}}" DataContext="{Binding PlacementTarget.DataContext, RelativeSource={RelativeSource Self}}"> <MenuItem Header="Restore" Command="{Binding RestoreCommand}" /> <MenuItem Header="Delete" Command="{Binding DeleteCommand}"/> </ContextMenu> </Setter.Value> </Setter> </Style> </ListView.ItemContainerStyle> <ListView.View> <GridView> <!-- My columns here --> <GridViewColumn> <GridViewColumn.CellTemplate> <DataTemplate> <ToggleButton IsChecked="{Binding Path=ContextMenu.IsOpen, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type ListViewItem}}}"/> </DataTemplate> </GridViewColumn.CellTemplate> </GridViewColumn> </GridView> </ListView.View> </ListView>
如果需要控制ContextMenu的弹出位置,还可以额外给ContextMenu设置Placement属性,比如设为Bottom让菜单在ListViewItem下方弹出。
内容的提问来源于stack exchange,提问作者Gary Francis
相关产品推荐
相关产品推荐

