0
votes

So I have a list view that displays post items (Delivery date, type, tracking number etc) and I have a context menu set up that either opens up the tracking website or copies the tracking number to the clipboard.

What I want is for the contextmenu only to appear for listitems that have a tracking number. I've got the idea of changing the visibility of the contextmenu but it's the binding to the tracking number I'm having the trouble with.

<ContextMenu x:Key="MyElementMenu">
    <MenuItem Header="Track Item" Click="MenuItem_Click"></MenuItem>
    <MenuItem Header="Copy to Clipboard" Click="MenuItem_CopyToClipboard"></MenuItem>
</ContextMenu>


<!--Sets a context menu for each ListBoxItem in the current ListBox-->
<Style TargetType="{x:Type ListViewItem}">
    <Setter Property="ContextMenu" Value="{StaticResource MyElementMenu}"/>
</Style>

This is what I have currently.

2
Have you tried using a Converter? - Ginger Ninja
I think 'ContextMenu' would appear when you right click on the ListViewItem. So why not use the right click event and see if the clicked item has the tracking number property and then hide or show the context menu. - Ahmar

2 Answers

0
votes
<MyControl.Resources>       
    <BooleanToVisibilityConverter x:Key="BoolToVis"/>
</MyControl.Resources>

<!--Sets a context menu for each ListBoxItem in the current ListBox-->
<Style TargetType="{x:Type ListViewItem}">
  <Setter Property="ContextMenu">
    <Setter.Value>
      <ContextMenu IsEnabled="{Binding HasTrackingNumber}" Visibility="{Binding HasTrackingNumber, Converter={StaticResource BoolToVis}">
        <MenuItem Header="Track Item" Click="MenuItem_Click"></MenuItem>
        <MenuItem Header="Copy to Clipboard" Click="MenuItem_CopyToClipboard"></MenuItem>
      </ContextMenu>
    </Setter.Value>
  </Setter>  
</Style>

This should give you what you need. Not sure if you use the ContextMenu elsewhere, but if you dont you can always just set it in the style of the ListViewItem Style. Then you dont need to have it referenced from elsewhere. Either way its more about adding the Binding from the item. In your ListItem Viewmodel you could add something like:

public bool HasTrackingNumber => TrackingNumber == 0 || TrackingNumber == null;

(I dont know what type your tracking number is so you can do your own logic checks to know if it "has" a valid tracking number)

0
votes

That seems like a case for a trigger:

<Style TargetType="{x:Type ListViewItem}">
    <Setter Property="ContextMenu" Value="{StaticResource MyElementMenu}"/>
    <Style.Triggers>
        <!-- 
        Maybe the tracking number property is called something else, maybe it's 0 
        instead of null when absent. You didn't say. 
        -->
        <DataTrigger Binding="{Binding TrackingNumber}" Value="{x:Null}">
            <Setter Property="ContextMenu" Value="{x:Null}"/>
        </DataTrigger>
    </Style.Triggers>
</Style>