Vincular ContextMenu's MenuItem visibilidad a ListView selección
-
06-07-2019 - |
Pregunta
Tengo un control de usuario con un ListView que contiene elementos simples de una ObservableCollection. Me gustaría que el ContextMenu de ese ListView contenga elementos dependiendo de lo que esté seleccionado en el ListView. Si no se selecciona ningún elemento, algunos elementos de menú no deberían estar visibles.
Mi conversor ni siquiera se llama cuando abro el ContextMenu. El enlace parece estar mal, encuentro esto en la ventana de salida:
System.Windows.Data Error: 4: No se puede encontrar el origen para el enlace con la referencia 'ElementName = listView'. BindingExpression: Path = SelectedItem; DataItem = nulo; el elemento de destino es 'MenuItem' (Nombre = ''); la propiedad de destino es 'Visibilidad' (tipo 'Visibilidad')
No entiendo lo que está mal y no pude resolverlo buscando en la web.
Aquí hay un código simplificado:
<UserControl x:Class="MyApp.DatabaseControl"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:l="clr-namespace:MyApp"
Height="Auto"
Width="Auto">
<UserControl.Resources>
<l:ValueToVisibilityConverter x:Key="valueToVisibility" />
</UserControl.Resources>
<Grid>
<ListView x:Name="listView" ItemsSource="{Binding Persons}">
<ListView.View>
<GridView>
<GridViewColumn Width="140" Header="First Name" DisplayMemberBinding="{Binding FirstName}"/>
<GridViewColumn Width="140" Header="Last Name" DisplayMemberBinding="{Binding LastName}" />
</GridView>
</ListView.View>
<ListView.ContextMenu>
<ContextMenu>
<MenuItem
Header="Open"
Visibility="{Binding SelectedItem, ElementName=listView, Converter={StaticResource valueToVisibility}}"/>
<Separator/>
<MenuItem Header="Add..."/>
<MenuItem Header="Remove"/>
</ContextMenu>
</ListView.ContextMenu>
</ListView>
</Grid>
¡Muchas gracias!
Solución
El problema es que el ContextMenu
no está en el mismo árbol visual que el ListBox
, por lo tanto, los enlaces no encuentran el ListBox
. Si se une a PlacementTarget
, eso debería ser el truco:
<MenuItem Header="Open"
Visibility="{Binding RelativeSource={RelativeSource FindAncestor,
AncestorType=ContextMenu}, Path=PlacementTarget.SelectedItem,
Converter={StaticResource valueToVisibility}}" />