WPF MenuItem IsChecked Binding not working
Asked Answered
D

1

7

Anyone know why the menu item binding does not work ?

<ToggleButton Name="toggleButton" Checked="checkBoxPublish_Checked" >
    <ToggleButton.Resources>
        <converters:BooleanToHiddenVisibility x:Key="boolToVis"/>
    </ToggleButton.Resources>
    <Grid>
        <Image  Height="auto"  HorizontalAlignment="Left" Margin="5" Name="image1" Stretch="Fill" VerticalAlignment="Top" Width="auto"  />
        <Viewbox >
            <TextBlock Text="Blocked" Opacity="0.7" Foreground="Red"   Visibility="{Binding Path=IsChecked, ElementName=toggleButton, Converter={StaticResource boolToVis}}"/>
        </Viewbox>
    </Grid>
    <ToggleButton.ContextMenu>
        <ContextMenu StaysOpen="True" >
            <MenuItem x:Name="menuItemBlock" Header="Block" Click="menuItemClick"  IsCheckable="True" IsChecked="{Binding ElementName=toggleButton, Path=IsChecked}"/>
            <MenuItem x:Name="menuItemIgnorePtz" Header="Ignore Ptz" Click="menuItemClick"  IsCheckable="True" />
        </ContextMenu>
    </ToggleButton.ContextMenu>
</ToggleButton>
Deaton answered 25/5, 2010 at 12:42 Comment(0)
S
8

I'm guessing that it is the contextmenu you have problem using data binding with.

The togglebutton is not in the logical tree of the contextmenu so it can't find the togglebutton using ElementName, see Link

That is why you get an error for that binding in your output window in VS:

System.Windows.Data Error: 4 : Cannot find source for binding with reference 'ElementName=toggleButton'. BindingExpression:Path=IsChecked; DataItem=null; target element is 'MenuItem' (Name='menuItemBlock'); target property is 'IsChecked' (type 'Boolean')

To fix, look up the toggle button using FindAncestor:

<MenuItem 
  Header="Block" 
  IsCheckable="True" 
  IsChecked="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType=ContextMenu}, Path=PlacementTarget.IsChecked}" />
      
Slippy answered 25/5, 2010 at 18:37 Comment(1)
When I first read this, I didn't realise that you have to bind to your datasource via the ContextMenu.PlacementTarget property (rather than, say, anything else sourced via the RelativeSource extension), as that's the way to get back to the containing control's visual tree. However, that was probably just me being a bit slow and I've now got it (and fixed my problem). Thanks for the help. +1.Spondaic

© 2022 - 2024 — McMap. All rights reserved.