I'm attempting to setup a MenuItem
that will have a submenu of page numbers that can be selected. I want to bind the ItemsSource
to a list of page numbers (actually to the PageCount with a converter creating the list) and then bind the IsChecked
property of each MenuItem
in the sub-menu to the PageIndex. My problem is with the second binding as it too requires a converter, but that converter need to know the page number that the MenuItem
represents, but I cannot figure out how to pass that information to the converter. Here's what I've tried so far.
<MenuItem Header="_Goto Page"
ItemsSource="{Binding
Path=CurrentImage.PageCount,
Converter={StaticResource countToList}}">
<MenuItem.ItemContainerStyle>
<Style TargetType="MenuItem">
<Setter Property="IsCheckable"
Value="True"/>
<Setter Property="IsChecked"
Value="{Binding
ElementName=MainWindow,
Path=CurrentImage.PageIndex,
Mode=TwoWay,
Converter={StaticResource pageNumChecked},
ConverterParameter={Binding
RelativeSource={RelativeSource Self},
Path=Content}}"/>
</Style>
</MenuItem.ItemContainerStyle>
</MenuItem>
Of course the problem is that the ConverterParameter
cannot be bound as it is not a DependencyProperty
. So my question is how can I pass in the information I need or is there another way to do this.
Note: I already tried putting the MenuItem
s inside of a ListBox
which worked really well as far as the bindings are concerned, but caused the sub-menu to behave in a non-standard way. That is when you opened the sub-menu the entire ListBox
was treated as one MenuItem
.
Edit
So here's what I've gotten to work so far. I tried binding to a hidden ListBox
but when I bound the MenuItem.ItemsSource
to the 'ListBox.Items' I got the list of int
s instead of a list of ListBoxItem
s which I needed to get the IsSelected
property. So I ended up using Quartermeister's suggestion of using MultiBinding to get the IsChecked
property to bind to the PageIndex
in OneWay
mode. To handle the other direction I used an event handler on the Click
event. It's worth noting that at first I had IsCheckable
set to true
and was working with the Checked
event, but that resulted is some odd behaviors.
<MenuItem x:Name="GotoPageMenuItem" Header="_Goto Page"
ItemsSource="{Binding Path=CurrentImage.PageCount,
Converter={StaticResource countToList}}">
<MenuItem.ItemContainerStyle>
<Style TargetType="MenuItem">
<Setter Property="IsCheckable"
Value="False"/>
<EventSetter Event="Click"
Handler="GotoPageMenuItem_Click"/>
<Setter Property="IsChecked">
<Setter.Value>
<MultiBinding Converter="{StaticResource pageNumChecked}"
Mode="OneWay">
<Binding RelativeSource="{RelativeSource FindAncestor,
AncestorType={x:Type Window}}"
Path="CurrentImage.PageIndex"
Mode="OneWay"/>
<Binding RelativeSource="{RelativeSource Self}"
Path="Header"
Mode="OneWay"/>
</MultiBinding>
</Setter.Value>
</Setter>
</Style>
</MenuItem.ItemContainerStyle>
</MenuItem>
And here's the GotoPageMenuItem_Click
code
private void GotoPageMenuItem_Click(object sender, RoutedEventArgs e)
{
var item = sender as MenuItem;
if (item != null)
{
//If the item is already checked then we don't need to do anything
if (!item.IsChecked)
{
var pageNum = (int)item.Header;
CurrentImage.PageIndex = (pageNum - 1);
}
}
}