开发者

WPF - Do not show Context menu when ListView is empty

I have a ContextMenu bind to ListView, but I don't want to be the menu shown when the ListView is empty. I tried direct binding to element, tried binding using FindAncestor, but none of these works and the menu is always shown when I click right mouse button in the ListView. What would 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;
        }
开发者_StackOverflow社区    }
    public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
    {
        throw new NotImplementedException();
    }                
}

Thanks in advance!


Use the ContextMenuService.IsEnabled property to prevent the ContextMenu from being shown. Something like:

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

using the converter that returns True or False.

Since the binding is now on the ListView itself, you could also use a Binding with a RelativeSource of Self instead of having to use ElementName, or you could bind directly to the DataContext by setting the path to Logins.Count (assuming Logins has its own Count property).


The easiest way to do this is to listen to the ListView's ContextMenuOpening event. You can then perform whatever logic you want and cancel the menu from opening.


Your binding wont work. The Visibility property is not a boolean, it's an enum. you should use the built-in converter BooleanToVisibilityConverter.


Thanks for the answer, sorry my fault, I copied wrong converter from clipboard here. I had it returning return Visibility.Visible or Visibility.Hidden, but it didn't solve my problem.

Strange is that when I do this:

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

I get a ContextMenu with empty string, regardless the ListView has items 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 the button content changes correctly according to ListView items count! It seems that ListView has to have other binding, FindAncestor with AncestorType=ListView didn't work as well and I'm out of ideas :-(

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜