I am using a context menu on a wpf treeview and I am pretty much there as to what I want. Before I explain the problem let me explain what the XAML definition for the context menu is doing.
For each menu item in the context menu we have a command that either disables or enables the menu item based on the commands CanExecute method. Each command will set the IsEnabled property of the corresponding menu item depending on the result of CanExecute.
IsEnabled for each the menu item is bound to a BooleanToVisibilityConverter which converts the the IsEnabled bool value to a Collapse or Visible value to be bound the Visibility propery of the menu item. This again works fine and my menu items are displaying and hiding fine.
Now for the problem. In the XAML below we have two menu items(addCategoryMenuItem and removeCategoryMenuItem) above a separator. I am trying to MultiBinding to the IsEnabled property of these two menu items via a custom implementation of IMultiValueConverter (MultiBooleanToVisibilityConverter) so that when the two menu items are disabled I can set the Visibility property of the Separator to collapsed and hence hide the separator when the menu items are disabled.
For the Convert method in my Converter(MultiBooleanToVisibilityConverter) the parameter value (object [] values) I get two items in the array that hold the value "{DependencyProperty.UnsetValue}". These cannot be cast to boolean values and hence my Visibility value cannot be worked out.
Maybe is has something do with ElementName used in the MultiBinding. Can it not find the element? I have tried using RelativeSource i.e find ancestor etc. But I just got confused. I have spent hours on this so now I leave it to the community.
Kind regards
Mohammad
<ContextMenu x:Key="CategoryMenu">
<ContextMenu.ItemContainerStyle>
<Style TargetType="{x:Type Control}">
<Setter Property="Visibility" Value="{Binding Path=IsEnabled, RelativeSource={RelativeSource Self}, Mode=OneWay, Converter={StaticResource booleanToVisibilityConverter}}" />
</Style>
</ContextMenu.ItemContainerStyle>
<ContextMenu.Items>
<MenuItem x:Name="addCategoryMenuItem" Header="add category" Command="{Binding AddCategory}">
<MenuItem.Icon>
<Image Source="/Images/add.png" Width="16" Height="16" />
</MenuItem.Icon>
</MenuItem>
<MenuItem x:Name="removeCategoryMenuItem" Header="remove category" Command="{Binding RemoveCategory}">
<MenuItem.Icon>
<Image Source="/Images/remove.png" Width="16" Height="16" />
</MenuItem.Icon>
</MenuItem>
<Separator>
<Separator.Visibility>
<MultiBinding Converter="{StaticResource multiBooleanToVisibilityConverter}">
<Binding Mode="OneWay" ElementName="addCategoryMenuItem" Path="IsEnabled" />
<Binding Mode="OneWay" ElementName="removeCategoryMenuItem" Path="IsEnabled" />
</MultiBinding>
</Separator.Visibility>
</Separator>
<MenuItem x:Name="refreshCategoryMenuItem" Header="refresh" Command="{Binding RefreshCategory}">
<MenuItem.Icon>
<Image Source="/Images/refresh.png" Width="16" Height="16" />
</MenuItem.Icon>
</MenuItem>
</ContextMenu.Items>
</ContextMenu>
Ok, after some rest I have managed to solve it. I had to use RelativeSource and FindAncestor to get the context menu object and then access the items collection and then use an indexer value to get the menu item. I think it would be better if I could use the menu item name as I don't like magic numbers in my code or indeed xaml.