views:

81

answers:

5

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;
        }
    }
    public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
    {
        throw new NotImplementedException();
    }                
}

Thanks in advance!

A: 

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

Muad'Dib
A: 

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 :-(

Gustaff
A: 

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.

rossisdead
Thanks for the answer, I know it can be done in code, but I wanted to have it done exactly in the XAML using Binding.
Gustaff
A: 

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).

Quartermeister
Accepted as an answer, this is what I was looking for!
Gustaff
A: 

Quartermeister thanks for the help, binding to ContextMenuServise exactly as you wrote!

P.S. I tried to find the "Accept as answer" icon but I cannot see it, maybe because I don't have enough reputation points?

Gustaff
@Gustaff: Welcome to StackOverflow! You can accept an answer by clicking on the check mark next to the answer. You can find out more here: http://meta.stackoverflow.com/questions/5234/how-does-accepting-an-answer-work. Also, when you post a response like this you should do it by commenting on an answer rather than posting it as a new answer.
Quartermeister
Gustaff
I posted a question about accepting answers here http://meta.stackoverflow.com/questions/59209/asked-as-an-unregistered-user-now-registered-and-cannot-accept-answer , I'm curious to read how to do it!
Gustaff
@Quartermeister - It works now, I can see the checkmark and offcourse I clicked it :-)
Gustaff