سؤال

I can't figure out where I'm going wrong here. Hopefully one of you can help.

I have a Window that contains a TabControl. The TabControl has a ContextMenu with a checkable item for "always-on-top" behavior. I want to bind this checkable item to the containing Window's boolean Topmost property.

No matter what I do, the binding fails and I get a "Cannot find source for binding" error in my debug output.

(These excerpts are greatly simplified from my actual code. I hope I didn't accidentally cut out anything relevant.)

First I tried this:

<Window x:Name="myWindow" (blah blah other properties)>
    <TabControl x:Name="tabControl">
        <TabControl.ContextMenu>
            <ContextMenu>
                <MenuItem Header="Always on Top" IsCheckable="True"
                          IsChecked="{Binding ElementName=myWindow,
                                              Path=Topmost,
                                              Mode=TwoWay}"/>
            </ContextMenu>
        ...

That didn't work. Is it because the MenuItem is inside of the Window "myWindow"? Do I need to use a RelativeSource Ancestor binding?

So I tried this:

<Window x:Name="myWindow" (blah blah other properties)>
    <TabControl x:Name="tabControl">
        <TabControl.ContextMenu>
            <ContextMenu>
                <MenuItem Header="Always on Top" IsCheckable="True"
                          IsChecked="{Binding RelativeSource={
                                                  RelativeSource FindAncestor,
                                                  AncestorType={x:Type Window}
                                              },
                                              Path=Topmost,
                                              Mode=TwoWay}"/>
            </ContextMenu>
        ...

That didn't work either.

So now I'm stuck. How do I make this binding work?

Note: My code-behind is not doing anything with these elements. Do I need to set Window.DataContext or something? That could possibly break other parts of this window.

هل كانت مفيدة؟

المحلول

Yes, whatever object your "TopMost" property is on will have to be set as the DataContext of your window. If its set as the DataContext of your Window then your control should be able to pickup the property from the ElementName binding you tried in your first example.

Your view will look at its DataContext for a property named "TopMost"

نصائح أخرى

As far as I remember Menu is drawn in a popup which is not actually a part of the visual tree of the Window. So it's better to try to use MVVM here and set IsChecked through the view model.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top