WPF Do not show context menu when ListView is empty.

I have a ContextMenu binding to a ListView, but I don't want this menu to display when the ListView is empty. I tried direct binding to the element, tried binding using FindAncestor, but none of these actions work, and the menu always displays when I right-click in the ListView. What will be the correct binding?

<Grid> <ListView x:Name="loginListView" ItemsSource="{Binding Logins}"> <ListView.View> <GridView> <GridViewColumn Width="140" Header="Login" DisplayMemberBinding="{Binding Login}"/> <GridViewColumn Width="140" Header="Password" DisplayMemberBinding="{Binding Password}" /> </GridView> </ListView.View> <ListView.ContextMenu> <ContextMenu> <MenuItem Header="Delete login" Visibility="{Binding ElementName=loginListView, Path=Items.Count, Converter={StaticResource VisibilityConverter}}"/> </ContextMenu> </ListView.ContextMenu> </ListView> 

 public class visibilityConverter: IValueConverter { public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture) { if ((int)value > 0) { return true; } else { return false; } } public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture) { throw new NotImplementedException(); } } 

Thanks in advance!

+4
source share
4 answers

Use the ContextMenuService.IsEnabled property to prevent ContextMenu from being displayed. Sort of:

 <ListView x:Name="loginListView" ItemsSource="{Binding Logins}" ContextMenuService.IsEnabled="{Binding ElementName=loginListView, Path=Items.Count, Converter={StaticResource VisibilityConverter}}"> 

using a converter that returns True or False.

Since the binding is now in the ListView itself, you can also use the binding with RelativeSource Self, instead of using ElementName, or you can directly bind to the DataContext by setting the path to Logins.Count (provided that Logins has its own Count property).

+5
source

The easiest way to do this is to listen to the ListView ContextMenuOpening event. Then you can execute any logic and cancel opening the menu.

+1
source

Your mandatory use will not work. The Visibility property is not logical, it is an enumeration. You must use the built-in BooleanToVisibilityConverter .

0
source

Thanks for the answer, sorry, my mistake, I copied the wrong converter from the clipboard here. I had this returning Visibility.Visible or Visibility.Hidden, but this did not solve my problem.

The strange thing is that when I do this:

 <ListView.ContextMenu> <ContextMenu> <MenuItem Header="{Binding ElementName=loginListView, Path=Items.Count}"/> </ContextMenu> </ListView.ContextMenu> 

I get ContextMenu with an empty string, regardless of the ListView elements or not! But in the same form when I do this:

 <Button Content="{Binding ElementName=loginListView, Path=Items.Count}" Name="deleteButton" Width="100" Height="30" HorizontalContentAlignment="Center" /> 

I see that the content of the button changes correctly according to the number of ListView elements! It seems that the ListView should have a different binding, FindAncestor with AncestorType = ListView doesn't work either, and I have no ideas: - (

0
source

All Articles