C# 尝试绑定MenuItem的IsChecked属性时感到困惑

C# 尝试绑定MenuItem的IsChecked属性时感到困惑,c#,wpf,xaml,data-binding,menuitem,C#,Wpf,Xaml,Data Binding,Menuitem,在查看StackOverflow和其他网站后,我发现人们在将属性和命令绑定到MenuItems和ContextMenus时遇到了很多问题,因为ContextMenu不是WPF可视树的一部分。不管怎么说,我已经尝试了一些不同的解决方案,但没有任何运气 我有一个菜单项,它是上下文菜单的一部分。ContextMenu是窗口的一部分,该窗口在其代码隐藏中绑定到ViewModel,如下所示: public partial class Window1 : Window { public MainWi

在查看StackOverflow和其他网站后,我发现人们在将属性和命令绑定到
MenuItems
ContextMenus
时遇到了很多问题,因为
ContextMenu
不是WPF可视树的一部分。不管怎么说,我已经尝试了一些不同的解决方案,但没有任何运气

我有一个
菜单项
,它是
上下文菜单
的一部分。
ContextMenu
是窗口的一部分,该窗口在其代码隐藏中绑定到ViewModel,如下所示:

public partial class Window1 : Window
{
    public MainWindowViewModel ViewModel { get { return DataContext as MainWindowViewModel; } } 

    public Window1()
    {
        InitializeComponent();

        //There is a property in the App.xaml.cs file that refers to MainWindowViewModel
        DataContext = App.MainWindowViewModel = new MainWindowViewModel();
    }
}
我试图在
MainWindowViewModel
中绑定到的属性:

private bool _askBeforeDownloading_Checked = true;

public bool AskBeforeDownloading_Checked
{
    get { return _askBeforeDownloading_Checked; }
    set
    {
        _askBeforeDownloading_Checked = value;
        NotifyPropertyChange(() => AskBeforeDownloading_Checked);
    }
}
我当前在XAML中的尝试:

<Button Name="Button_1" >
    <Button.ContextMenu>
        <ContextMenu x:Name="MainContextMenu" DataContext="{Binding PlacementTarget.DataContext, RelativeSource={RelativeSource Self}}" >
            <MenuItem >
                <MenuItem IsCheckable="True" IsChecked="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType=ContextMenu}, Path=PlacementTarget.AskBeforeDownloading_Checked}" />
            </MenuItem>
        </ContextMenu>
    </Button.ContextMenu>
</Button>

我根据上的公认答案提出了我当前的XAML,以及。我错过了什么?我没有收到任何输出错误,但未检查
菜单项。是否有我没有对PlacementTarget执行的操作

更新:我想重要的是要注意我的
上下文菜单
按钮
的子控件。我已经将它添加到我的XAML中


更新2:在我的应用程序上使用Snoop后,我发现我的
按钮
自动继承自
MainWindowViewModel
。但是,我忽略了可能会影响我的代码的父菜单项。我已经更新了我的XAML,很抱歉第一次没有更新

DataContext
是从
继承而来的,因此不需要在那里的绑定中编写任何特殊内容

<Button Name="Button_1" >
    <Button.ContextMenu>
        <ContextMenu x:Name="MainContextMenu" DataContext="{Binding PlacementTarget.DataContext, RelativeSource={RelativeSource Self}}" >
            <MenuItem IsCheckable="True" IsChecked="{Binding AskBeforeDownloading_Checked}" />
        </ContextMenu>
    </Button.ContextMenu>
</Button>

在这两种方法中,我更喜欢第一种方法,因为如果要将更多的项/属性绑定到
按钮.DataContext
属性,
DataContext
是从
继承而来的,因此不需要在绑定中编写任何特殊内容

<Button Name="Button_1" >
    <Button.ContextMenu>
        <ContextMenu x:Name="MainContextMenu" DataContext="{Binding PlacementTarget.DataContext, RelativeSource={RelativeSource Self}}" >
            <MenuItem IsCheckable="True" IsChecked="{Binding AskBeforeDownloading_Checked}" />
        </ContextMenu>
    </Button.ContextMenu>
</Button>

在这两种方法中,我更喜欢第一种方法,因为如果要将更多的项/属性绑定到
按钮.DataContext
属性,那么它可以减少代码量。

您需要添加PlacementTarget.DataContext。请参阅下面的代码

<Button Name="Button_1" >
        <Button.ContextMenu>
            <ContextMenu x:Name="MainContextMenu">
                <MenuItem IsCheckable="True" IsChecked="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType=ContextMenu}, Path=PlacementTarget.DataContext.AskBeforeDownloading_Checked}" />
            </ContextMenu>
        </Button.ContextMenu>
    </Button>

您需要添加PlacementTarget.DataContext。请参阅下面的代码

<Button Name="Button_1" >
        <Button.ContextMenu>
            <ContextMenu x:Name="MainContextMenu">
                <MenuItem IsCheckable="True" IsChecked="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType=ContextMenu}, Path=PlacementTarget.DataContext.AskBeforeDownloading_Checked}" />
            </ContextMenu>
        </Button.ContextMenu>
    </Button>


执行此操作后,是否应检查我的
菜单项
?因为它不是,这让我相信这里还发生了其他事情。@Ericafterdark
MenuItem.IsChecked
应该与按钮.DataContext.AskBeforeDownloading\u Checked匹配。如果它没有保持同步,那么我会再次检查
按钮.DataContext
是否与您的
MainWindowViewModel
相同。我经常推荐一个第三方工具,比如如果你在调试数据绑定时遇到问题,我也更喜欢你的第一个例子,我同意Snoop对这个问题很有用。但是,我认为可能需要注意的是,我没有在XAML中为我的
按钮设置
DataContext
。这样行吗,还是会有问题?此外,如果我的
MenuItem
是另一个
MenuItem
的孩子,这也会是一个问题吗?签出更新2在我的帖子中。看起来我忽略了一些可能会影响我的程序的内容。@是的,
DataContext
属性如果没有特别设置,则会被子控件继承,因此,如果它已经在层次结构中进一步设置为
MainWindowViewModel
,则无需显式设置
按钮。DataContext
。此外,树中第二个
的存在不应影响此处发布的任何一个代码示例:)执行此操作后,是否应检查我的
菜单项
?因为它不是,这让我相信这里还发生了其他事情。@Ericafterdark
MenuItem.IsChecked
应该与按钮.DataContext.AskBeforeDownloading\u Checked
匹配。如果它没有保持同步,那么我会再次检查
按钮.DataContext
是否与您的
MainWindowViewModel
相同。我经常推荐一个第三方工具,比如如果你在调试数据绑定时遇到问题,我也更喜欢你的第一个例子,我同意Snoop对这个问题很有用。但是,我认为可能需要注意的是,我没有在XAML中为我的
按钮设置
DataContext
。这样行吗,还是会有问题?此外,如果我的
MenuItem
是另一个
MenuItem
的孩子,这也会是一个问题吗?签出更新2在我的帖子中。看起来我忽略了一些可能会影响我的程序的内容。@是的,
DataContext
属性如果没有特别设置,则会被子控件继承,因此,如果它已经在层次结构中进一步设置为
MainWindowViewModel
,则无需显式设置
按钮。DataContext
。此外,树中第二个
的存在不应影响此处发布的代码示例:)