I had a similar issue when trying to implement a menu that was backed by an enumeration. I wanted to be able to set the underlying property (which was an enum) to the value associated with the menu item.
In my example, I attached two properties to an MenuItem:
public static readonly DependencyProperty EnumTargetProperty = DependencyProperty.RegisterAttached(
"EnumTarget",
typeof(object),
typeof(MenuItem),
new PropertyMetadata(null, EnumTargetChangedCallback)
);
public static readonly DependencyProperty EnumValueProperty = DependencyProperty.RegisterAttached(
"EnumValue",
typeof(object),
typeof(MenuItem),
new PropertyMetadata(null, EnumValueChangedCallback)
);
And the markup looks like this:
<MenuItem.ItemContainerStyle>
<Style TargetType="MenuItem">
<Setter Property="IsCheckable" Value="True"/>
<Setter Property="local:EnumMenuItem.EnumValue" Value="{Binding EnumMember}"/>
<Setter Property="local:EnumMenuItem.EnumTarget" Value="{Binding RelativeSource={RelativeSource AncestorType=local:MainWindow}, Path=DataContext.Settings.AutoUpdateModel.Ring}"/>
<Setter Property="Header" Value="{Binding DisplayName}"/>
<Setter Property="ToolTip" Value="{Binding ToolTip}"/>
</Style>
</MenuItem.ItemContainerStyle>
The item source for the parent menu item was bound to an MarkupExtension implementation that provided values for each member in the enum.
Now, when the menu item was checked, I used this code to set the value of the property without removing the binding.
menuItem.Checked += (sender, args) =>
{
var checkedMenuItem = (MenuItem)sender;
var targetEnum = checkedMenuItem.GetValue(EnumTargetProperty);
var menuItemValue = checkedMenuItem.GetValue(EnumValueProperty);
if (targetEnum != null && menuItemValue != null)
{
var bindingExpression = BindingOperations.GetBindingExpression(d, EnumTargetProperty);
if (bindingExpression != null)
{
var enumTargetObject = bindingExpression.ResolvedSource;
if (enumTargetObject != null)
{
var propertyName = bindingExpression.ResolvedSourcePropertyName;
if (!string.IsNullOrEmpty(propertyName))
{
var propInfo = enumTargetObject.GetType().GetProperty(propertyName);
if (propInfo != null)
{
propInfo.SetValue(enumTargetObject, menuItemValue);
}
}
}
}
}
};
This seems to work fine for my scenario with a complex path.
I hope this helps out!