1

I have a ContextMenu for TreeView items declared in the treeview:

<TreeView  ItemsSource="{Binding countries, Mode=TwoWay}" SelectedItemChanged="TreeView_SelectedItemChanged">
    <TreeView.Resources>
        <HierarchicalDataTemplate DataType="{x:Type myapp:City}"  ItemsSource="{Binding Cities}">
            <StackPanel Orientation="Horizontal" ContextMenu="{StaticResource CityItem}">
                <TextBlock Text="{Binding CityName}" FontSize="14" Foreground="Bisque"/>
                ...

And the ContextMenu itself declared as:

<ContextMenu x:Key ="CityItem"  StaysOpen="true" Foreground="Bisque">
    <MenuItem Header="Edit City"  CommandParameter="{Binding Parent, RelativeSource={RelativeSource Self}}" Click="EditCityClick"/>
    <MenuItem Header="DeleteCity" CommandParameter="{Binding Parent, RelativeSource={RelativeSource Self}}" Click="DeleteCityClick"/>
</ContextMenu>

Well, at this point everything is working

private void DeleteCityClick(object sender, RoutedEventArgs e)
{
    City city = ((FrameworkElement)e.OriginalSource).DataContext as City;
        ...
}

I can access to the city object, modify, delete, whatever and everything is updated in the gui acording to the changes in Cities and City properties (onpropertychanged is working fine).

The question is how can i disable a ContextMenuItem binding IsEnabled to a City object property? Let's say

public bool IsEnabled { get; set;}

I tried several ways, but idk how to access to the source object (City) from the ContextMenu MenuItem.

Thanks!

Edited: Sorry for the typo but:

public string IsEnabled { get; set;}

Actually is:

public bool IsEnabled { get; set;}

Edit 2:

Funny "not a wpf..."

enter image description here

Hüsk3rDü
  • 583
  • 1
  • 4
  • 12
  • If I'm not mistaken, why can't you simply use `SelectedNode` of the treeview? If the context menu is opened and one of the options is clicked, the `SelectedNode` cast to `City` should give you what you need. (And you won't need to use CommandParameter) – Keyur PATEL Jul 21 '17 at 07:20
  • Actually I may be wrong, it is possible to right click a node without selecting in TreeView (I'm used to datagrids where that's not possible). Take a look [at this link](https://stackoverflow.com/questions/2527/find-node-clicked-under-context-menu), its for winforms but converting to WPF should not be that difficult. – Keyur PATEL Jul 21 '17 at 07:22
  • `sender` is `MenuItem`, [find](https://stackoverflow.com/q/16231375/1997232) to which `Menu` it belongs, then [find](https://stackoverflow.com/q/1884117/1997232) on which element menu is, then `DataContext` of this element is your `City`. – Sinatr Jul 21 '17 at 07:28
  • Sorry, maybe i didn't explain... I have no issues accessing to the City object... What i want is to bind the Isenabled property of the City object to the IsEnabled property of the MenuItem, i don't know how to bind it – Hüsk3rDü Jul 21 '17 at 07:39

2 Answers2

3

Try this:

<MenuItem ... IsEnabled="{Binding PlacementTarget.DataContext.IsEnabled, RelativeSource={RelativeSource AncestorType=ContextMenu}}" />

It binds to the DataContext of the PlacementTarget of the parent ContextMenu, which should be a City object.

mm8
  • 163,881
  • 10
  • 57
  • 88
2

I think your problem is, that ContextMenu is in resources. So you can use PlacementTarget to get it bound.

<ContextMenu x:Key ="CityItem" IsEnabled="{Binding PlacementTarget.DataContext.IsEnabled, RelativeSource={RelativeSource Self}}">
Rekshino
  • 6,954
  • 2
  • 19
  • 44
  • Well, i don't need a converter since City object has a bool property called IsEnabled. On the other hand, i only want to disable one ContextMenuitem. I tried with the IsEnabled property of City set to false, but still not working... – Hüsk3rDü Jul 21 '17 at 10:06
  • See my answer. Wrong type of ancestor. And you don't need a converter. – mm8 Jul 21 '17 at 10:11
  • @ Hüsk3rDü Have you written in your question? public string IsEnabled { get; set;} – Rekshino Jul 21 '17 at 10:24
  • Not if you want to disable an individual MenuItem. – mm8 Jul 21 '17 at 10:25
  • @Rekshino public bool IsEnabled {get; set;} is defined in City object... – Hüsk3rDü Jul 21 '17 at 10:33
  • @mm8 But disabled must be a ContextMenu, or? No, I think you are right: in question ContextMenuItem(therefore I was confused, there are either ContextMenu or MenuItem), in comment MenuItem – Rekshino Jul 21 '17 at 10:33
  • @Hüsk3rDü Then you have to ajust you question – Rekshino Jul 21 '17 at 10:34
  • @Rekshino, god... you're right... it's a simple bool, not a string, no converters needed – Hüsk3rDü Jul 21 '17 at 10:37
  • @Hüsk3rDü I have adjusted my answer. It works for (whole) ContextMenu, if you want it for MenuItem, then see answer from mm8 – Rekshino Jul 21 '17 at 10:38